LLVM  17.0.0git
Signals.inc
Go to the documentation of this file.
1 //===- Signals.cpp - Generic Unix Signals Implementation -----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines some helpful functions for dealing with the possibility of
10 // Unix signals occurring while your program is running.
11 //
12 //===----------------------------------------------------------------------===//
13 //
14 // This file is extremely careful to only do signal-safe things while in a
15 // signal handler. In particular, memory allocation and acquiring a mutex
16 // while in a signal handler should never occur. ManagedStatic isn't usable from
17 // a signal handler for 2 reasons:
18 //
19 // 1. Creating a new one allocates.
20 // 2. The signal handler could fire while llvm_shutdown is being processed, in
21 // which case the ManagedStatic is in an unknown state because it could
22 // already have been destroyed, or be in the process of being destroyed.
23 //
24 // Modifying the behavior of the signal handlers (such as registering new ones)
25 // can acquire a mutex, but all this guarantees is that the signal handler
26 // behavior is only modified by one thread at a time. A signal handler can still
27 // fire while this occurs!
28 //
29 // Adding work to a signal handler requires lock-freedom (and assume atomics are
30 // always lock-free) because the signal handler could fire while new work is
31 // being added.
32 //
33 //===----------------------------------------------------------------------===//
34 
35 #include "Unix.h"
36 #include "llvm/ADT/STLExtras.h"
37 #include "llvm/Config/config.h"
38 #include "llvm/Demangle/Demangle.h"
39 #include "llvm/Support/ExitCodes.h"
42 #include "llvm/Support/Format.h"
44 #include "llvm/Support/Mutex.h"
45 #include "llvm/Support/Program.h"
48 #include <algorithm>
49 #include <string>
50 #ifdef HAVE_BACKTRACE
51 #include BACKTRACE_HEADER // For backtrace().
52 #endif
53 #if HAVE_SIGNAL_H
54 #include <signal.h>
55 #endif
56 #if HAVE_SYS_STAT_H
57 #include <sys/stat.h>
58 #endif
59 #if HAVE_DLFCN_H
60 #include <dlfcn.h>
61 #endif
62 #if HAVE_MACH_MACH_H
63 #include <mach/mach.h>
64 #endif
65 #if HAVE_LINK_H
66 #include <link.h>
67 #endif
68 #ifdef HAVE__UNWIND_BACKTRACE
69 // FIXME: We should be able to use <unwind.h> for any target that has an
70 // _Unwind_Backtrace function, but on FreeBSD the configure test passes
71 // despite the function not existing, and on Android, <unwind.h> conflicts
72 // with <link.h>.
73 #ifdef __GLIBC__
74 #include <unwind.h>
75 #else
76 #undef HAVE__UNWIND_BACKTRACE
77 #endif
78 #endif
79 
80 using namespace llvm;
81 
82 static void SignalHandler(int Sig); // defined below.
83 static void InfoSignalHandler(int Sig); // defined below.
84 
85 using SignalHandlerFunctionType = void (*)();
86 /// The function to call if ctrl-c is pressed.
87 static std::atomic<SignalHandlerFunctionType> InterruptFunction =
88  ATOMIC_VAR_INIT(nullptr);
89 static std::atomic<SignalHandlerFunctionType> InfoSignalFunction =
90  ATOMIC_VAR_INIT(nullptr);
91 /// The function to call on SIGPIPE (one-time use only).
92 static std::atomic<SignalHandlerFunctionType> OneShotPipeSignalFunction =
93  ATOMIC_VAR_INIT(nullptr);
94 
95 namespace {
96 /// Signal-safe removal of files.
97 /// Inserting and erasing from the list isn't signal-safe, but removal of files
98 /// themselves is signal-safe. Memory is freed when the head is freed, deletion
99 /// is therefore not signal-safe either.
100 class FileToRemoveList {
101  std::atomic<char *> Filename = ATOMIC_VAR_INIT(nullptr);
102  std::atomic<FileToRemoveList *> Next = ATOMIC_VAR_INIT(nullptr);
103 
104  FileToRemoveList() = default;
105  // Not signal-safe.
106  FileToRemoveList(const std::string &str) : Filename(strdup(str.c_str())) {}
107 
108 public:
109  // Not signal-safe.
110  ~FileToRemoveList() {
111  if (FileToRemoveList *N = Next.exchange(nullptr))
112  delete N;
113  if (char *F = Filename.exchange(nullptr))
114  free(F);
115  }
116 
117  // Not signal-safe.
118  static void insert(std::atomic<FileToRemoveList *> &Head,
119  const std::string &Filename) {
120  // Insert the new file at the end of the list.
121  FileToRemoveList *NewHead = new FileToRemoveList(Filename);
122  std::atomic<FileToRemoveList *> *InsertionPoint = &Head;
123  FileToRemoveList *OldHead = nullptr;
124  while (!InsertionPoint->compare_exchange_strong(OldHead, NewHead)) {
125  InsertionPoint = &OldHead->Next;
126  OldHead = nullptr;
127  }
128  }
129 
130  // Not signal-safe.
131  static void erase(std::atomic<FileToRemoveList *> &Head,
132  const std::string &Filename) {
133  // Use a lock to avoid concurrent erase: the comparison would access
134  // free'd memory.
136  sys::SmartScopedLock<true> Writer(*Lock);
137 
138  for (FileToRemoveList *Current = Head.load(); Current;
139  Current = Current->Next.load()) {
140  if (char *OldFilename = Current->Filename.load()) {
141  if (OldFilename != Filename)
142  continue;
143  // Leave an empty filename.
144  OldFilename = Current->Filename.exchange(nullptr);
145  // The filename might have become null between the time we
146  // compared it and we exchanged it.
147  if (OldFilename)
148  free(OldFilename);
149  }
150  }
151  }
152 
153  // Signal-safe.
154  static void removeAllFiles(std::atomic<FileToRemoveList *> &Head) {
155  // If cleanup were to occur while we're removing files we'd have a bad time.
156  // Make sure we're OK by preventing cleanup from doing anything while we're
157  // removing files. If cleanup races with us and we win we'll have a leak,
158  // but we won't crash.
159  FileToRemoveList *OldHead = Head.exchange(nullptr);
160 
161  for (FileToRemoveList *currentFile = OldHead; currentFile;
162  currentFile = currentFile->Next.load()) {
163  // If erasing was occuring while we're trying to remove files we'd look
164  // at free'd data. Take away the path and put it back when done.
165  if (char *path = currentFile->Filename.exchange(nullptr)) {
166  // Get the status so we can determine if it's a file or directory. If we
167  // can't stat the file, ignore it.
168  struct stat buf;
169  if (stat(path, &buf) != 0)
170  continue;
171 
172  // If this is not a regular file, ignore it. We want to prevent removal
173  // of special files like /dev/null, even if the compiler is being run
174  // with the super-user permissions.
175  if (!S_ISREG(buf.st_mode))
176  continue;
177 
178  // Otherwise, remove the file. We ignore any errors here as there is
179  // nothing else we can do.
180  unlink(path);
181 
182  // We're done removing the file, erasing can safely proceed.
183  currentFile->Filename.exchange(path);
184  }
185  }
186 
187  // We're done removing files, cleanup can safely proceed.
188  Head.exchange(OldHead);
189  }
190 };
191 static std::atomic<FileToRemoveList *> FilesToRemove = ATOMIC_VAR_INIT(nullptr);
192 
193 /// Clean up the list in a signal-friendly manner.
194 /// Recall that signals can fire during llvm_shutdown. If this occurs we should
195 /// either clean something up or nothing at all, but we shouldn't crash!
196 struct FilesToRemoveCleanup {
197  // Not signal-safe.
198  ~FilesToRemoveCleanup() {
199  FileToRemoveList *Head = FilesToRemove.exchange(nullptr);
200  if (Head)
201  delete Head;
202  }
203 };
204 } // namespace
205 
206 static StringRef Argv0;
207 
208 /// Signals that represent requested termination. There's no bug or failure, or
209 /// if there is, it's not our direct responsibility. For whatever reason, our
210 /// continued execution is no longer desirable.
211 static const int IntSigs[] = {SIGHUP, SIGINT, SIGTERM, SIGUSR2};
212 
213 /// Signals that represent that we have a bug, and our prompt termination has
214 /// been ordered.
215 static const int KillSigs[] = {SIGILL,
216  SIGTRAP,
217  SIGABRT,
218  SIGFPE,
219  SIGBUS,
220  SIGSEGV,
221  SIGQUIT
222 #ifdef SIGSYS
223  ,
224  SIGSYS
225 #endif
226 #ifdef SIGXCPU
227  ,
228  SIGXCPU
229 #endif
230 #ifdef SIGXFSZ
231  ,
232  SIGXFSZ
233 #endif
234 #ifdef SIGEMT
235  ,
236  SIGEMT
237 #endif
238 };
239 
240 /// Signals that represent requests for status.
241 static const int InfoSigs[] = {SIGUSR1
242 #ifdef SIGINFO
243  ,
244  SIGINFO
245 #endif
246 };
247 
248 static const size_t NumSigs = std::size(IntSigs) + std::size(KillSigs) +
249  std::size(InfoSigs) + 1 /* SIGPIPE */;
250 
251 static std::atomic<unsigned> NumRegisteredSignals = ATOMIC_VAR_INIT(0);
252 static struct {
253  struct sigaction SA;
254  int SigNo;
255 } RegisteredSignalInfo[NumSigs];
256 
257 #if defined(HAVE_SIGALTSTACK)
258 // Hold onto both the old and new alternate signal stack so that it's not
259 // reported as a leak. We don't make any attempt to remove our alt signal
260 // stack if we remove our signal handlers; that can't be done reliably if
261 // someone else is also trying to do the same thing.
262 static stack_t OldAltStack;
263 LLVM_ATTRIBUTE_USED static void *NewAltStackPointer;
264 
265 static void CreateSigAltStack() {
266  const size_t AltStackSize = MINSIGSTKSZ + 64 * 1024;
267 
268  // If we're executing on the alternate stack, or we already have an alternate
269  // signal stack that we're happy with, there's nothing for us to do. Don't
270  // reduce the size, some other part of the process might need a larger stack
271  // than we do.
272  if (sigaltstack(nullptr, &OldAltStack) != 0 ||
273  OldAltStack.ss_flags & SS_ONSTACK ||
274  (OldAltStack.ss_sp && OldAltStack.ss_size >= AltStackSize))
275  return;
276 
277  stack_t AltStack = {};
278  AltStack.ss_sp = static_cast<char *>(safe_malloc(AltStackSize));
279  NewAltStackPointer = AltStack.ss_sp; // Save to avoid reporting a leak.
280  AltStack.ss_size = AltStackSize;
281  if (sigaltstack(&AltStack, &OldAltStack) != 0)
282  free(AltStack.ss_sp);
283 }
284 #else
285 static void CreateSigAltStack() {}
286 #endif
287 
288 static void RegisterHandlers() { // Not signal-safe.
289  // The mutex prevents other threads from registering handlers while we're
290  // doing it. We also have to protect the handlers and their count because
291  // a signal handler could fire while we're registeting handlers.
292  static ManagedStatic<sys::SmartMutex<true>> SignalHandlerRegistrationMutex;
293  sys::SmartScopedLock<true> Guard(*SignalHandlerRegistrationMutex);
294 
295  // If the handlers are already registered, we're done.
296  if (NumRegisteredSignals.load() != 0)
297  return;
298 
299  // Create an alternate stack for signal handling. This is necessary for us to
300  // be able to reliably handle signals due to stack overflow.
301  CreateSigAltStack();
302 
303  enum class SignalKind { IsKill, IsInfo };
304  auto registerHandler = [&](int Signal, SignalKind Kind) {
305  unsigned Index = NumRegisteredSignals.load();
306  assert(Index < std::size(RegisteredSignalInfo) &&
307  "Out of space for signal handlers!");
308 
309  struct sigaction NewHandler;
310 
311  switch (Kind) {
312  case SignalKind::IsKill:
313  NewHandler.sa_handler = SignalHandler;
314  NewHandler.sa_flags = SA_NODEFER | SA_RESETHAND | SA_ONSTACK;
315  break;
316  case SignalKind::IsInfo:
317  NewHandler.sa_handler = InfoSignalHandler;
318  NewHandler.sa_flags = SA_ONSTACK;
319  break;
320  }
321  sigemptyset(&NewHandler.sa_mask);
322 
323  // Install the new handler, save the old one in RegisteredSignalInfo.
324  sigaction(Signal, &NewHandler, &RegisteredSignalInfo[Index].SA);
325  RegisteredSignalInfo[Index].SigNo = Signal;
326  ++NumRegisteredSignals;
327  };
328 
329  for (auto S : IntSigs)
330  registerHandler(S, SignalKind::IsKill);
331  for (auto S : KillSigs)
332  registerHandler(S, SignalKind::IsKill);
333  if (OneShotPipeSignalFunction)
334  registerHandler(SIGPIPE, SignalKind::IsKill);
335  for (auto S : InfoSigs)
336  registerHandler(S, SignalKind::IsInfo);
337 }
338 
340  // Restore all of the signal handlers to how they were before we showed up.
341  for (unsigned i = 0, e = NumRegisteredSignals.load(); i != e; ++i) {
342  sigaction(RegisteredSignalInfo[i].SigNo, &RegisteredSignalInfo[i].SA,
343  nullptr);
344  --NumRegisteredSignals;
345  }
346 }
347 
348 /// Process the FilesToRemove list.
349 static void RemoveFilesToRemove() {
350  FileToRemoveList::removeAllFiles(FilesToRemove);
351 }
352 
353 void sys::CleanupOnSignal(uintptr_t Context) {
354  int Sig = (int)Context;
355 
356  if (llvm::is_contained(InfoSigs, Sig)) {
357  InfoSignalHandler(Sig);
358  return;
359  }
360 
361  RemoveFilesToRemove();
362 
363  if (llvm::is_contained(IntSigs, Sig) || Sig == SIGPIPE)
364  return;
365 
367 }
368 
369 // The signal handler that runs.
370 static void SignalHandler(int Sig) {
371  // Restore the signal behavior to default, so that the program actually
372  // crashes when we return and the signal reissues. This also ensures that if
373  // we crash in our signal handler that the program will terminate immediately
374  // instead of recursing in the signal handler.
376 
377  // Unmask all potentially blocked kill signals.
378  sigset_t SigMask;
379  sigfillset(&SigMask);
380  sigprocmask(SIG_UNBLOCK, &SigMask, nullptr);
381 
382  {
383  RemoveFilesToRemove();
384 
385  if (Sig == SIGPIPE)
386  if (auto OldOneShotPipeFunction =
387  OneShotPipeSignalFunction.exchange(nullptr))
388  return OldOneShotPipeFunction();
389 
390  bool IsIntSig = llvm::is_contained(IntSigs, Sig);
391  if (IsIntSig)
392  if (auto OldInterruptFunction = InterruptFunction.exchange(nullptr))
393  return OldInterruptFunction();
394 
395  if (Sig == SIGPIPE || IsIntSig) {
396  raise(Sig); // Execute the default handler.
397  return;
398  }
399  }
400 
401  // Otherwise if it is a fault (like SEGV) run any handler.
403 
404 #ifdef __s390__
405  // On S/390, certain signals are delivered with PSW Address pointing to
406  // *after* the faulting instruction. Simply returning from the signal
407  // handler would continue execution after that point, instead of
408  // re-raising the signal. Raise the signal manually in those cases.
409  if (Sig == SIGILL || Sig == SIGFPE || Sig == SIGTRAP)
410  raise(Sig);
411 #endif
412 }
413 
414 static void InfoSignalHandler(int Sig) {
415  SaveAndRestore SaveErrnoDuringASignalHandler(errno);
416  if (SignalHandlerFunctionType CurrentInfoFunction = InfoSignalFunction)
417  CurrentInfoFunction();
418 }
419 
420 void llvm::sys::RunInterruptHandlers() { RemoveFilesToRemove(); }
421 
422 void llvm::sys::SetInterruptFunction(void (*IF)()) {
423  InterruptFunction.exchange(IF);
424  RegisterHandlers();
425 }
426 
427 void llvm::sys::SetInfoSignalFunction(void (*Handler)()) {
428  InfoSignalFunction.exchange(Handler);
429  RegisterHandlers();
430 }
431 
432 void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) {
433  OneShotPipeSignalFunction.exchange(Handler);
434  RegisterHandlers();
435 }
436 
438  // Send a special return code that drivers can check for, from sysexits.h.
439  exit(EX_IOERR);
440 }
441 
442 // The public API
443 bool llvm::sys::RemoveFileOnSignal(StringRef Filename, std::string *ErrMsg) {
444  // Ensure that cleanup will occur as soon as one file is added.
445  static ManagedStatic<FilesToRemoveCleanup> FilesToRemoveCleanup;
446  *FilesToRemoveCleanup;
447  FileToRemoveList::insert(FilesToRemove, Filename.str());
448  RegisterHandlers();
449  return false;
450 }
451 
452 // The public API
454  FileToRemoveList::erase(FilesToRemove, Filename.str());
455 }
456 
457 /// Add a function to be called when a signal is delivered to the process. The
458 /// handler can have a cookie passed to it to identify what instance of the
459 /// handler it is.
461  void *Cookie) { // Signal-safe.
462  insertSignalHandler(FnPtr, Cookie);
463  RegisterHandlers();
464 }
465 
466 #if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && HAVE_LINK_H && \
467  (defined(__linux__) || defined(__FreeBSD__) || \
468  defined(__FreeBSD_kernel__) || defined(__NetBSD__))
469 struct DlIteratePhdrData {
470  void **StackTrace;
471  int depth;
472  bool first;
473  const char **modules;
474  intptr_t *offsets;
475  const char *main_exec_name;
476 };
477 
478 static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
479  DlIteratePhdrData *data = (DlIteratePhdrData *)arg;
480  const char *name = data->first ? data->main_exec_name : info->dlpi_name;
481  data->first = false;
482  for (int i = 0; i < info->dlpi_phnum; i++) {
483  const auto *phdr = &info->dlpi_phdr[i];
484  if (phdr->p_type != PT_LOAD)
485  continue;
486  intptr_t beg = info->dlpi_addr + phdr->p_vaddr;
487  intptr_t end = beg + phdr->p_memsz;
488  for (int j = 0; j < data->depth; j++) {
489  if (data->modules[j])
490  continue;
491  intptr_t addr = (intptr_t)data->StackTrace[j];
492  if (beg <= addr && addr < end) {
493  data->modules[j] = name;
494  data->offsets[j] = addr - info->dlpi_addr;
495  }
496  }
497  }
498  return 0;
499 }
500 
501 /// If this is an ELF platform, we can find all loaded modules and their virtual
502 /// addresses with dl_iterate_phdr.
503 static bool findModulesAndOffsets(void **StackTrace, int Depth,
504  const char **Modules, intptr_t *Offsets,
505  const char *MainExecutableName,
506  StringSaver &StrPool) {
507  DlIteratePhdrData data = {StackTrace, Depth, true,
508  Modules, Offsets, MainExecutableName};
509  dl_iterate_phdr(dl_iterate_phdr_cb, &data);
510  return true;
511 }
512 #else
513 /// This platform does not have dl_iterate_phdr, so we do not yet know how to
514 /// find all loaded DSOs.
515 static bool findModulesAndOffsets(void **StackTrace, int Depth,
516  const char **Modules, intptr_t *Offsets,
517  const char *MainExecutableName,
518  StringSaver &StrPool) {
519  return false;
520 }
521 #endif // defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && ...
522 
523 #if ENABLE_BACKTRACES && defined(HAVE__UNWIND_BACKTRACE)
524 static int unwindBacktrace(void **StackTrace, int MaxEntries) {
525  if (MaxEntries < 0)
526  return 0;
527 
528  // Skip the first frame ('unwindBacktrace' itself).
529  int Entries = -1;
530 
531  auto HandleFrame = [&](_Unwind_Context *Context) -> _Unwind_Reason_Code {
532  // Apparently we need to detect reaching the end of the stack ourselves.
533  void *IP = (void *)_Unwind_GetIP(Context);
534  if (!IP)
535  return _URC_END_OF_STACK;
536 
537  assert(Entries < MaxEntries && "recursively called after END_OF_STACK?");
538  if (Entries >= 0)
539  StackTrace[Entries] = IP;
540 
541  if (++Entries == MaxEntries)
542  return _URC_END_OF_STACK;
543  return _URC_NO_REASON;
544  };
545 
546  _Unwind_Backtrace(
547  [](_Unwind_Context *Context, void *Handler) {
548  return (*static_cast<decltype(HandleFrame) *>(Handler))(Context);
549  },
550  static_cast<void *>(&HandleFrame));
551  return std::max(Entries, 0);
552 }
553 #endif
554 
555 // In the case of a program crash or fault, print out a stack trace so that the
556 // user has an indication of why and where we died.
557 //
558 // On glibc systems we have the 'backtrace' function, which works nicely, but
559 // doesn't demangle symbols.
561 #if ENABLE_BACKTRACES
562  static void *StackTrace[256];
563  int depth = 0;
564 #if defined(HAVE_BACKTRACE)
565  // Use backtrace() to output a backtrace on Linux systems with glibc.
566  if (!depth)
567  depth = backtrace(StackTrace, static_cast<int>(std::size(StackTrace)));
568 #endif
569 #if defined(HAVE__UNWIND_BACKTRACE)
570  // Try _Unwind_Backtrace() if backtrace() failed.
571  if (!depth)
572  depth =
573  unwindBacktrace(StackTrace, static_cast<int>(std::size(StackTrace)));
574 #endif
575  if (!depth)
576  return;
577  // If "Depth" is not provided by the caller, use the return value of
578  // backtrace() for printing a symbolized stack trace.
579  if (!Depth)
580  Depth = depth;
581  if (printSymbolizedStackTrace(Argv0, StackTrace, Depth, OS))
582  return;
583  OS << "Stack dump without symbol names (ensure you have llvm-symbolizer in "
584  "your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point "
585  "to it):\n";
586 #if HAVE_DLFCN_H && HAVE_DLADDR
587  int width = 0;
588  for (int i = 0; i < depth; ++i) {
589  Dl_info dlinfo;
590  dladdr(StackTrace[i], &dlinfo);
591  const char *name = strrchr(dlinfo.dli_fname, '/');
592 
593  int nwidth;
594  if (!name)
595  nwidth = strlen(dlinfo.dli_fname);
596  else
597  nwidth = strlen(name) - 1;
598 
599  if (nwidth > width)
600  width = nwidth;
601  }
602 
603  for (int i = 0; i < depth; ++i) {
604  Dl_info dlinfo;
605  dladdr(StackTrace[i], &dlinfo);
606 
607  OS << format("%-2d", i);
608 
609  const char *name = strrchr(dlinfo.dli_fname, '/');
610  if (!name)
611  OS << format(" %-*s", width, dlinfo.dli_fname);
612  else
613  OS << format(" %-*s", width, name + 1);
614 
615  OS << format(" %#0*lx", (int)(sizeof(void *) * 2) + 2,
616  (unsigned long)StackTrace[i]);
617 
618  if (dlinfo.dli_sname != nullptr) {
619  OS << ' ';
620  int res;
621  char *d = itaniumDemangle(dlinfo.dli_sname, nullptr, nullptr, &res);
622  if (!d)
623  OS << dlinfo.dli_sname;
624  else
625  OS << d;
626  free(d);
627 
628  OS << format(" + %tu", (static_cast<const char *>(StackTrace[i]) -
629  static_cast<const char *>(dlinfo.dli_saddr)));
630  }
631  OS << '\n';
632  }
633 #elif defined(HAVE_BACKTRACE)
634  backtrace_symbols_fd(StackTrace, Depth, STDERR_FILENO);
635 #endif
636 #endif
637 }
638 
639 static void PrintStackTraceSignalHandler(void *) {
641 }
642 
644 
645 /// When an error signal (such as SIGABRT or SIGSEGV) is delivered to the
646 /// process, print a stack trace and then exit.
648  bool DisableCrashReporting) {
649  ::Argv0 = Argv0;
650 
651  AddSignalHandler(PrintStackTraceSignalHandler, nullptr);
652 
653 #if defined(__APPLE__) && ENABLE_CRASH_OVERRIDES
654  // Environment variable to disable any kind of crash dialog.
655  if (DisableCrashReporting || getenv("LLVM_DISABLE_CRASH_REPORT")) {
656  mach_port_t self = mach_task_self();
657 
658  exception_mask_t mask = EXC_MASK_CRASH;
659 
660  kern_return_t ret = task_set_exception_ports(
661  self, mask, MACH_PORT_NULL,
662  EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
663  (void)ret;
664  }
665 #endif
666 }
i
i
Definition: README.txt:29
MemoryBuffer.h
LLVM_ATTRIBUTE_USED
#define LLVM_ATTRIBUTE_USED
Definition: Compiler.h:139
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::sys::PrintStackTrace
void PrintStackTrace(raw_ostream &OS, int Depth=0)
Print the stack trace using the given raw_ostream object.
FileSystem.h
intptr_t
name
static const char * name
Definition: SMEABIPass.cpp:49
llvm::AMDGPUISD::IF
@ IF
Definition: AMDGPUISelLowering.h:362
llvm::logicalview::LVAttributeKind::Filename
@ Filename
llvm::Depth
@ Depth
Definition: SIMachineScheduler.h:36
llvm::sys::RunSignalHandlers
void RunSignalHandlers()
Definition: Signals.cpp:97
llvm::sys::path::end
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:235
ret
to esp esp setne al movzbw ax esp setg cl movzbw cx cmove cx cl jne LBB1_2 esp ret(also really horrible code on ppc). This is due to the expand code for 64-bit compares. GCC produces multiple branches
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:891
STLExtras.h
llvm::sys::RunInterruptHandlers
void RunInterruptHandlers()
This function runs all the registered interrupt handlers, including the removal of files registered b...
llvm::sys::SetInterruptFunction
void SetInterruptFunction(void(*IF)())
This function registers a function to be called when the user "interrupts" the program (typically by ...
Unix.h
Format.h
F
#define F(x, y, z)
Definition: MD5.cpp:55
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
llvm::sys::SignalHandlerCallback
void(*)(void *) SignalHandlerCallback
Definition: Signals.h:61
ExitCodes.h
llvm::sys::SetInfoSignalFunction
void SetInfoSignalFunction(void(*Handler)())
Registers a function to be called when an "info" signal is delivered to the process.
int
Clang compiles this i1 i64 store i64 i64 store i64 i64 store i64 i64 store i64 align Which gets codegen d xmm0 movaps rbp movaps rbp movaps rbp movaps rbp rbp rbp rbp rbp It would be better to have movq s of instead of the movaps s LLVM produces ret int
Definition: README.txt:536
llvm::ManagedStatic
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
Definition: ManagedStatic.h:83
insertSignalHandler
static void insertSignalHandler(sys::SignalHandlerCallback FnPtr, void *Cookie)
Definition: Signals.cpp:111
llvm::sys::DefaultOneShotPipeSignalHandler
void DefaultOneShotPipeSignalHandler()
On Unix systems, this function exits with an "IO error" exit code.
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
llvm::sys::DisableSystemDialogsOnCrash
void DisableSystemDialogsOnCrash()
Disable all system dialog boxes that appear when the process crashes.
printSymbolizedStackTrace
static LLVM_ATTRIBUTE_USED bool printSymbolizedStackTrace(StringRef Argv0, void **StackTrace, int Depth, llvm::raw_ostream &OS)
Helper that launches llvm-symbolizer and symbolizes a backtrace.
Definition: Signals.cpp:141
Index
uint32_t Index
Definition: ELFObjHandler.cpp:83
SaveAndRestore.h
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:31
llvm::sys::SmartScopedLock
std::lock_guard< SmartMutex< mt_only > > SmartScopedLock
Definition: Mutex.h:69
size
i< reg-> size
Definition: README.txt:166
llvm::is_contained
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:1869
llvm::sys::AddSignalHandler
void AddSignalHandler(SignalHandlerCallback FnPtr, void *Cookie)
Add a function to be called when an abort/kill signal is delivered to the process.
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::sys::SetOneShotPipeSignalFunction
void SetOneShotPipeSignalFunction(void(*Handler)())
Registers a function to be called in a "one-shot" manner when a pipe signal is delivered to the proce...
info
lazy value info
Definition: LazyValueInfo.cpp:58
llvm::StringSaver
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
Definition: StringSaver.h:21
llvm::size
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1716
FileUtilities.h
Demangle.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
if
if(llvm_vc STREQUAL "") set(fake_version_inc "$
Definition: CMakeLists.txt:14
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::SaveAndRestore
A utility class that uses RAII to save and restore the value of a variable.
Definition: SaveAndRestore.h:23
llvm::format
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
Mutex.h
llvm::ELF::PT_LOAD
@ PT_LOAD
Definition: ELF.h:1382
llvm::sys::unregisterHandlers
void unregisterHandlers()
j
return j(j<< 16)
llvm::c_str
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
Definition: WindowsSupport.h:196
llvm::sys::CleanupOnSignal
void CleanupOnSignal(uintptr_t Context)
This function does the following:
llvm::sys::DontRemoveFileOnSignal
void DontRemoveFileOnSignal(StringRef Filename)
This function removes a file from the list of files to be removed on signal delivery.
exit
declare void exit(i32) noreturn nounwind This compiles into
Definition: README.txt:1072
N
#define N
Program.h
llvm::itaniumDemangle
char * itaniumDemangle(const char *mangled_name, char *buf, size_t *n, int *status)
Definition: ItaniumDemangle.cpp:368
findModulesAndOffsets
static bool findModulesAndOffsets(void **StackTrace, int Depth, const char **Modules, intptr_t *Offsets, const char *MainExecutableName, StringSaver &StrPool)
shuffles::mask
auto mask(ShuffFunc S, unsigned Length, OptArgs... args) -> MaskT
Definition: HexagonISelDAGToDAGHVX.cpp:903
raw_ostream.h
d
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int int int d
Definition: README.txt:418
llvm::SI::KernelInputOffsets::Offsets
Offsets
Offsets in bytes from the start of the input buffer.
Definition: SIInstrInfo.h:1332
llvm::sys::RemoveFileOnSignal
bool RemoveFileOnSignal(StringRef Filename, std::string *ErrMsg=nullptr)
This function registers signal handlers to ensure that if a signal gets delivered that the named file...
llvm::safe_malloc
LLVM_ATTRIBUTE_RETURNS_NONNULL void * safe_malloc(size_t Sz)
Definition: MemAlloc.h:25
llvm::sys::PrintStackTraceOnErrorSignal
void PrintStackTraceOnErrorSignal(StringRef Argv0, bool DisableCrashReporting=false)
When an error signal (such as SIGABRT or SIGSEGV) is delivered to the process, print a stack trace an...