LLVM  15.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.
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[] = {
212  SIGHUP, SIGINT, SIGTERM, SIGUSR2
213 };
214 
215 /// Signals that represent that we have a bug, and our prompt termination has
216 /// been ordered.
217 static const int KillSigs[] = {
218  SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV, SIGQUIT
219 #ifdef SIGSYS
220  , SIGSYS
221 #endif
222 #ifdef SIGXCPU
223  , SIGXCPU
224 #endif
225 #ifdef SIGXFSZ
226  , SIGXFSZ
227 #endif
228 #ifdef SIGEMT
229  , SIGEMT
230 #endif
231 };
232 
233 /// Signals that represent requests for status.
234 static const int InfoSigs[] = {
235  SIGUSR1
236 #ifdef SIGINFO
237  , SIGINFO
238 #endif
239 };
240 
241 static const size_t NumSigs =
242  array_lengthof(IntSigs) + array_lengthof(KillSigs) +
243  array_lengthof(InfoSigs) + 1 /* SIGPIPE */;
244 
245 
246 static std::atomic<unsigned> NumRegisteredSignals = ATOMIC_VAR_INIT(0);
247 static struct {
248  struct sigaction SA;
249  int SigNo;
250 } RegisteredSignalInfo[NumSigs];
251 
252 #if defined(HAVE_SIGALTSTACK)
253 // Hold onto both the old and new alternate signal stack so that it's not
254 // reported as a leak. We don't make any attempt to remove our alt signal
255 // stack if we remove our signal handlers; that can't be done reliably if
256 // someone else is also trying to do the same thing.
257 static stack_t OldAltStack;
258 LLVM_ATTRIBUTE_USED static void *NewAltStackPointer;
259 
260 static void CreateSigAltStack() {
261  const size_t AltStackSize = MINSIGSTKSZ + 64 * 1024;
262 
263  // If we're executing on the alternate stack, or we already have an alternate
264  // signal stack that we're happy with, there's nothing for us to do. Don't
265  // reduce the size, some other part of the process might need a larger stack
266  // than we do.
267  if (sigaltstack(nullptr, &OldAltStack) != 0 ||
268  OldAltStack.ss_flags & SS_ONSTACK ||
269  (OldAltStack.ss_sp && OldAltStack.ss_size >= AltStackSize))
270  return;
271 
272  stack_t AltStack = {};
273  AltStack.ss_sp = static_cast<char *>(safe_malloc(AltStackSize));
274  NewAltStackPointer = AltStack.ss_sp; // Save to avoid reporting a leak.
275  AltStack.ss_size = AltStackSize;
276  if (sigaltstack(&AltStack, &OldAltStack) != 0)
277  free(AltStack.ss_sp);
278 }
279 #else
280 static void CreateSigAltStack() {}
281 #endif
282 
283 static void RegisterHandlers() { // Not signal-safe.
284  // The mutex prevents other threads from registering handlers while we're
285  // doing it. We also have to protect the handlers and their count because
286  // a signal handler could fire while we're registeting handlers.
287  static ManagedStatic<sys::SmartMutex<true>> SignalHandlerRegistrationMutex;
288  sys::SmartScopedLock<true> Guard(*SignalHandlerRegistrationMutex);
289 
290  // If the handlers are already registered, we're done.
291  if (NumRegisteredSignals.load() != 0)
292  return;
293 
294  // Create an alternate stack for signal handling. This is necessary for us to
295  // be able to reliably handle signals due to stack overflow.
296  CreateSigAltStack();
297 
298  enum class SignalKind { IsKill, IsInfo };
299  auto registerHandler = [&](int Signal, SignalKind Kind) {
300  unsigned Index = NumRegisteredSignals.load();
301  assert(Index < array_lengthof(RegisteredSignalInfo) &&
302  "Out of space for signal handlers!");
303 
304  struct sigaction NewHandler;
305 
306  switch (Kind) {
307  case SignalKind::IsKill:
308  NewHandler.sa_handler = SignalHandler;
309  NewHandler.sa_flags = SA_NODEFER | SA_RESETHAND | SA_ONSTACK;
310  break;
311  case SignalKind::IsInfo:
312  NewHandler.sa_handler = InfoSignalHandler;
313  NewHandler.sa_flags = SA_ONSTACK;
314  break;
315  }
316  sigemptyset(&NewHandler.sa_mask);
317 
318  // Install the new handler, save the old one in RegisteredSignalInfo.
319  sigaction(Signal, &NewHandler, &RegisteredSignalInfo[Index].SA);
320  RegisteredSignalInfo[Index].SigNo = Signal;
321  ++NumRegisteredSignals;
322  };
323 
324  for (auto S : IntSigs)
325  registerHandler(S, SignalKind::IsKill);
326  for (auto S : KillSigs)
327  registerHandler(S, SignalKind::IsKill);
328  if (OneShotPipeSignalFunction)
329  registerHandler(SIGPIPE, SignalKind::IsKill);
330  for (auto S : InfoSigs)
331  registerHandler(S, SignalKind::IsInfo);
332 }
333 
335  // Restore all of the signal handlers to how they were before we showed up.
336  for (unsigned i = 0, e = NumRegisteredSignals.load(); i != e; ++i) {
337  sigaction(RegisteredSignalInfo[i].SigNo,
338  &RegisteredSignalInfo[i].SA, nullptr);
339  --NumRegisteredSignals;
340  }
341 }
342 
343 /// Process the FilesToRemove list.
344 static void RemoveFilesToRemove() {
345  FileToRemoveList::removeAllFiles(FilesToRemove);
346 }
347 
348 void sys::CleanupOnSignal(uintptr_t Context) {
349  int Sig = (int)Context;
350 
351  if (llvm::is_contained(InfoSigs, Sig)) {
352  InfoSignalHandler(Sig);
353  return;
354  }
355 
356  RemoveFilesToRemove();
357 
358  if (llvm::is_contained(IntSigs, Sig) || Sig == SIGPIPE)
359  return;
360 
362 }
363 
364 // The signal handler that runs.
365 static void SignalHandler(int Sig) {
366  // Restore the signal behavior to default, so that the program actually
367  // crashes when we return and the signal reissues. This also ensures that if
368  // we crash in our signal handler that the program will terminate immediately
369  // instead of recursing in the signal handler.
371 
372  // Unmask all potentially blocked kill signals.
373  sigset_t SigMask;
374  sigfillset(&SigMask);
375  sigprocmask(SIG_UNBLOCK, &SigMask, nullptr);
376 
377  {
378  RemoveFilesToRemove();
379 
380  if (Sig == SIGPIPE)
381  if (auto OldOneShotPipeFunction =
382  OneShotPipeSignalFunction.exchange(nullptr))
383  return OldOneShotPipeFunction();
384 
385  bool IsIntSig = llvm::is_contained(IntSigs, Sig);
386  if (IsIntSig)
387  if (auto OldInterruptFunction = InterruptFunction.exchange(nullptr))
388  return OldInterruptFunction();
389 
390  if (Sig == SIGPIPE || IsIntSig) {
391  raise(Sig); // Execute the default handler.
392  return;
393  }
394  }
395 
396  // Otherwise if it is a fault (like SEGV) run any handler.
398 
399 #ifdef __s390__
400  // On S/390, certain signals are delivered with PSW Address pointing to
401  // *after* the faulting instruction. Simply returning from the signal
402  // handler would continue execution after that point, instead of
403  // re-raising the signal. Raise the signal manually in those cases.
404  if (Sig == SIGILL || Sig == SIGFPE || Sig == SIGTRAP)
405  raise(Sig);
406 #endif
407 }
408 
409 static void InfoSignalHandler(int Sig) {
410  SaveAndRestore<int> SaveErrnoDuringASignalHandler(errno);
411  if (SignalHandlerFunctionType CurrentInfoFunction = InfoSignalFunction)
412  CurrentInfoFunction();
413 }
414 
416  RemoveFilesToRemove();
417 }
418 
419 void llvm::sys::SetInterruptFunction(void (*IF)()) {
420  InterruptFunction.exchange(IF);
421  RegisterHandlers();
422 }
423 
424 void llvm::sys::SetInfoSignalFunction(void (*Handler)()) {
425  InfoSignalFunction.exchange(Handler);
426  RegisterHandlers();
427 }
428 
429 void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) {
430  OneShotPipeSignalFunction.exchange(Handler);
431  RegisterHandlers();
432 }
433 
435  // UNIX03 conformance requires a non-zero exit code and an error message
436  // to stderr when writing to a closed stdout fails.
437  errs() << "error: write on a pipe with no reader\n";
438 
439  // Send a special return code that drivers can check for, from sysexits.h.
440  exit(EX_IOERR);
441 }
442 
443 // The public API
445  std::string* ErrMsg) {
446  // Ensure that cleanup will occur as soon as one file is added.
447  static ManagedStatic<FilesToRemoveCleanup> FilesToRemoveCleanup;
448  *FilesToRemoveCleanup;
449  FileToRemoveList::insert(FilesToRemove, Filename.str());
450  RegisterHandlers();
451  return false;
452 }
453 
454 // The public API
456  FileToRemoveList::erase(FilesToRemove, Filename.str());
457 }
458 
459 /// Add a function to be called when a signal is delivered to the process. The
460 /// handler can have a cookie passed to it to identify what instance of the
461 /// handler it is.
463  void *Cookie) { // Signal-safe.
464  insertSignalHandler(FnPtr, Cookie);
465  RegisterHandlers();
466 }
467 
468 #if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && HAVE_LINK_H && \
469  (defined(__linux__) || defined(__FreeBSD__) || \
470  defined(__FreeBSD_kernel__) || defined(__NetBSD__))
471 struct DlIteratePhdrData {
472  void **StackTrace;
473  int depth;
474  bool first;
475  const char **modules;
476  intptr_t *offsets;
477  const char *main_exec_name;
478 };
479 
480 static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
481  DlIteratePhdrData *data = (DlIteratePhdrData*)arg;
482  const char *name = data->first ? data->main_exec_name : info->dlpi_name;
483  data->first = false;
484  for (int i = 0; i < info->dlpi_phnum; i++) {
485  const auto *phdr = &info->dlpi_phdr[i];
486  if (phdr->p_type != PT_LOAD)
487  continue;
488  intptr_t beg = info->dlpi_addr + phdr->p_vaddr;
489  intptr_t end = beg + phdr->p_memsz;
490  for (int j = 0; j < data->depth; j++) {
491  if (data->modules[j])
492  continue;
493  intptr_t addr = (intptr_t)data->StackTrace[j];
494  if (beg <= addr && addr < end) {
495  data->modules[j] = name;
496  data->offsets[j] = addr - info->dlpi_addr;
497  }
498  }
499  }
500  return 0;
501 }
502 
503 /// If this is an ELF platform, we can find all loaded modules and their virtual
504 /// addresses with dl_iterate_phdr.
505 static bool findModulesAndOffsets(void **StackTrace, int Depth,
506  const char **Modules, intptr_t *Offsets,
507  const char *MainExecutableName,
508  StringSaver &StrPool) {
509  DlIteratePhdrData data = {StackTrace, Depth, true,
510  Modules, Offsets, MainExecutableName};
511  dl_iterate_phdr(dl_iterate_phdr_cb, &data);
512  return true;
513 }
514 #else
515 /// This platform does not have dl_iterate_phdr, so we do not yet know how to
516 /// find all loaded DSOs.
517 static bool findModulesAndOffsets(void **StackTrace, int Depth,
518  const char **Modules, intptr_t *Offsets,
519  const char *MainExecutableName,
520  StringSaver &StrPool) {
521  return false;
522 }
523 #endif // defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && ...
524 
525 #if ENABLE_BACKTRACES && defined(HAVE__UNWIND_BACKTRACE)
526 static int unwindBacktrace(void **StackTrace, int MaxEntries) {
527  if (MaxEntries < 0)
528  return 0;
529 
530  // Skip the first frame ('unwindBacktrace' itself).
531  int Entries = -1;
532 
533  auto HandleFrame = [&](_Unwind_Context *Context) -> _Unwind_Reason_Code {
534  // Apparently we need to detect reaching the end of the stack ourselves.
535  void *IP = (void *)_Unwind_GetIP(Context);
536  if (!IP)
537  return _URC_END_OF_STACK;
538 
539  assert(Entries < MaxEntries && "recursively called after END_OF_STACK?");
540  if (Entries >= 0)
541  StackTrace[Entries] = IP;
542 
543  if (++Entries == MaxEntries)
544  return _URC_END_OF_STACK;
545  return _URC_NO_REASON;
546  };
547 
548  _Unwind_Backtrace(
549  [](_Unwind_Context *Context, void *Handler) {
550  return (*static_cast<decltype(HandleFrame) *>(Handler))(Context);
551  },
552  static_cast<void *>(&HandleFrame));
553  return std::max(Entries, 0);
554 }
555 #endif
556 
557 // In the case of a program crash or fault, print out a stack trace so that the
558 // user has an indication of why and where we died.
559 //
560 // On glibc systems we have the 'backtrace' function, which works nicely, but
561 // doesn't demangle symbols.
563 #if ENABLE_BACKTRACES
564  static void *StackTrace[256];
565  int depth = 0;
566 #if defined(HAVE_BACKTRACE)
567  // Use backtrace() to output a backtrace on Linux systems with glibc.
568  if (!depth)
569  depth = backtrace(StackTrace, static_cast<int>(array_lengthof(StackTrace)));
570 #endif
571 #if defined(HAVE__UNWIND_BACKTRACE)
572  // Try _Unwind_Backtrace() if backtrace() failed.
573  if (!depth)
574  depth = unwindBacktrace(StackTrace,
575  static_cast<int>(array_lengthof(StackTrace)));
576 #endif
577  if (!depth)
578  return;
579  // If "Depth" is not provided by the caller, use the return value of
580  // backtrace() for printing a symbolized stack trace.
581  if (!Depth)
582  Depth = depth;
583  if (printSymbolizedStackTrace(Argv0, StackTrace, Depth, OS))
584  return;
585  OS << "Stack dump without symbol names (ensure you have llvm-symbolizer in "
586  "your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point "
587  "to it):\n";
588 #if HAVE_DLFCN_H && HAVE_DLADDR
589  int width = 0;
590  for (int i = 0; i < depth; ++i) {
591  Dl_info dlinfo;
592  dladdr(StackTrace[i], &dlinfo);
593  const char* name = strrchr(dlinfo.dli_fname, '/');
594 
595  int nwidth;
596  if (!name) nwidth = strlen(dlinfo.dli_fname);
597  else nwidth = strlen(name) - 1;
598 
599  if (nwidth > width) width = nwidth;
600  }
601 
602  for (int i = 0; i < depth; ++i) {
603  Dl_info dlinfo;
604  dladdr(StackTrace[i], &dlinfo);
605 
606  OS << format("%-2d", i);
607 
608  const char* name = strrchr(dlinfo.dli_fname, '/');
609  if (!name) OS << format(" %-*s", width, dlinfo.dli_fname);
610  else OS << format(" %-*s", width, name+1);
611 
612  OS << format(" %#0*lx", (int)(sizeof(void*) * 2) + 2,
613  (unsigned long)StackTrace[i]);
614 
615  if (dlinfo.dli_sname != nullptr) {
616  OS << ' ';
617  int res;
618  char* d = itaniumDemangle(dlinfo.dli_sname, nullptr, nullptr, &res);
619  if (!d) OS << dlinfo.dli_sname;
620  else OS << d;
621  free(d);
622 
623  OS << format(" + %tu", (static_cast<const char*>(StackTrace[i])-
624  static_cast<const char*>(dlinfo.dli_saddr)));
625  }
626  OS << '\n';
627  }
628 #elif defined(HAVE_BACKTRACE)
629  backtrace_symbols_fd(StackTrace, Depth, STDERR_FILENO);
630 #endif
631 #endif
632 }
633 
634 static void PrintStackTraceSignalHandler(void *) {
636 }
637 
639 
640 /// When an error signal (such as SIGABRT or SIGSEGV) is delivered to the
641 /// process, print a stack trace and then exit.
643  bool DisableCrashReporting) {
644  ::Argv0 = Argv0;
645 
646  AddSignalHandler(PrintStackTraceSignalHandler, nullptr);
647 
648 #if defined(__APPLE__) && ENABLE_CRASH_OVERRIDES
649  // Environment variable to disable any kind of crash dialog.
650  if (DisableCrashReporting || getenv("LLVM_DISABLE_CRASH_REPORT")) {
651  mach_port_t self = mach_task_self();
652 
653  exception_mask_t mask = EXC_MASK_CRASH;
654 
655  kern_return_t ret = task_set_exception_ports(self,
656  mask,
657  MACH_PORT_NULL,
658  EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES,
659  THREAD_STATE_NONE);
660  (void)ret;
661  }
662 #endif
663 }
i
i
Definition: README.txt:29
MemoryBuffer.h
LLVM_ATTRIBUTE_USED
#define LLVM_ATTRIBUTE_USED
Definition: Compiler.h:138
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
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
llvm::AMDGPUISD::IF
@ IF
Definition: AMDGPUISelLowering.h:358
llvm::Depth
@ Depth
Definition: SIMachineScheduler.h:36
llvm::sys::RunSignalHandlers
void RunSignalHandlers()
Definition: Signals.cpp:96
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:893
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::Lock
static sys::Mutex Lock
Definition: NVPTXUtilities.cpp:39
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
IP
Definition: NVPTXLowerArgs.cpp:167
insertSignalHandler
static void insertSignalHandler(sys::SignalHandlerCallback FnPtr, void *Cookie)
Definition: Signals.cpp:110
llvm::dwarf::Index
Index
Definition: Dwarf.h:472
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:54
llvm::StringRef::str
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:249
llvm::array_lengthof
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLArrayExtras.h:29
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
llvm::sys::DisableSystemDialogsOnCrash
void DisableSystemDialogsOnCrash()
Disable all system dialog boxes that appear when the process crashes.
llvm::ELF::PT_LOAD
@ PT_LOAD
Definition: ELF.h:1337
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:140
Index
uint32_t Index
Definition: ELFObjHandler.cpp:82
SaveAndRestore.h
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
llvm::sys::SmartScopedLock
std::lock_guard< SmartMutex< mt_only > > SmartScopedLock
Definition: Mutex.h:71
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:1682
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:1598
FileUtilities.h
Demangle.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
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:21
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::sys::unregisterHandlers
void unregisterHandlers()
name
static const char * name
Definition: SVEIntrinsicOpts.cpp:74
j
return j(j<< 16)
llvm::c_str
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
Definition: WindowsSupport.h:193
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)
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:1320
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...