LLVM  14.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 RETSIGTYPE SignalHandler(int Sig); // defined below.
83 static RETSIGTYPE 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 RETSIGTYPE 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 RETSIGTYPE 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  // Send a special return code that drivers can check for, from sysexits.h.
436  exit(EX_IOERR);
437 }
438 
439 // The public API
441  std::string* ErrMsg) {
442  // Ensure that cleanup will occur as soon as one file is added.
443  static ManagedStatic<FilesToRemoveCleanup> FilesToRemoveCleanup;
444  *FilesToRemoveCleanup;
445  FileToRemoveList::insert(FilesToRemove, Filename.str());
446  RegisterHandlers();
447  return false;
448 }
449 
450 // The public API
452  FileToRemoveList::erase(FilesToRemove, Filename.str());
453 }
454 
455 /// Add a function to be called when a signal is delivered to the process. The
456 /// handler can have a cookie passed to it to identify what instance of the
457 /// handler it is.
459  void *Cookie) { // Signal-safe.
460  insertSignalHandler(FnPtr, Cookie);
461  RegisterHandlers();
462 }
463 
464 #if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && HAVE_LINK_H && \
465  (defined(__linux__) || defined(__FreeBSD__) || \
466  defined(__FreeBSD_kernel__) || defined(__NetBSD__))
467 struct DlIteratePhdrData {
468  void **StackTrace;
469  int depth;
470  bool first;
471  const char **modules;
472  intptr_t *offsets;
473  const char *main_exec_name;
474 };
475 
476 static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
477  DlIteratePhdrData *data = (DlIteratePhdrData*)arg;
478  const char *name = data->first ? data->main_exec_name : info->dlpi_name;
479  data->first = false;
480  for (int i = 0; i < info->dlpi_phnum; i++) {
481  const auto *phdr = &info->dlpi_phdr[i];
482  if (phdr->p_type != PT_LOAD)
483  continue;
484  intptr_t beg = info->dlpi_addr + phdr->p_vaddr;
485  intptr_t end = beg + phdr->p_memsz;
486  for (int j = 0; j < data->depth; j++) {
487  if (data->modules[j])
488  continue;
489  intptr_t addr = (intptr_t)data->StackTrace[j];
490  if (beg <= addr && addr < end) {
491  data->modules[j] = name;
492  data->offsets[j] = addr - info->dlpi_addr;
493  }
494  }
495  }
496  return 0;
497 }
498 
499 /// If this is an ELF platform, we can find all loaded modules and their virtual
500 /// addresses with dl_iterate_phdr.
501 static bool findModulesAndOffsets(void **StackTrace, int Depth,
502  const char **Modules, intptr_t *Offsets,
503  const char *MainExecutableName,
504  StringSaver &StrPool) {
505  DlIteratePhdrData data = {StackTrace, Depth, true,
506  Modules, Offsets, MainExecutableName};
507  dl_iterate_phdr(dl_iterate_phdr_cb, &data);
508  return true;
509 }
510 #else
511 /// This platform does not have dl_iterate_phdr, so we do not yet know how to
512 /// find all loaded DSOs.
513 static bool findModulesAndOffsets(void **StackTrace, int Depth,
514  const char **Modules, intptr_t *Offsets,
515  const char *MainExecutableName,
516  StringSaver &StrPool) {
517  return false;
518 }
519 #endif // defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && ...
520 
521 #if ENABLE_BACKTRACES && defined(HAVE__UNWIND_BACKTRACE)
522 static int unwindBacktrace(void **StackTrace, int MaxEntries) {
523  if (MaxEntries < 0)
524  return 0;
525 
526  // Skip the first frame ('unwindBacktrace' itself).
527  int Entries = -1;
528 
529  auto HandleFrame = [&](_Unwind_Context *Context) -> _Unwind_Reason_Code {
530  // Apparently we need to detect reaching the end of the stack ourselves.
531  void *IP = (void *)_Unwind_GetIP(Context);
532  if (!IP)
533  return _URC_END_OF_STACK;
534 
535  assert(Entries < MaxEntries && "recursively called after END_OF_STACK?");
536  if (Entries >= 0)
537  StackTrace[Entries] = IP;
538 
539  if (++Entries == MaxEntries)
540  return _URC_END_OF_STACK;
541  return _URC_NO_REASON;
542  };
543 
544  _Unwind_Backtrace(
545  [](_Unwind_Context *Context, void *Handler) {
546  return (*static_cast<decltype(HandleFrame) *>(Handler))(Context);
547  },
548  static_cast<void *>(&HandleFrame));
549  return std::max(Entries, 0);
550 }
551 #endif
552 
553 // In the case of a program crash or fault, print out a stack trace so that the
554 // user has an indication of why and where we died.
555 //
556 // On glibc systems we have the 'backtrace' function, which works nicely, but
557 // doesn't demangle symbols.
559 #if ENABLE_BACKTRACES
560  static void *StackTrace[256];
561  int depth = 0;
562 #if defined(HAVE_BACKTRACE)
563  // Use backtrace() to output a backtrace on Linux systems with glibc.
564  if (!depth)
565  depth = backtrace(StackTrace, static_cast<int>(array_lengthof(StackTrace)));
566 #endif
567 #if defined(HAVE__UNWIND_BACKTRACE)
568  // Try _Unwind_Backtrace() if backtrace() failed.
569  if (!depth)
570  depth = unwindBacktrace(StackTrace,
571  static_cast<int>(array_lengthof(StackTrace)));
572 #endif
573  if (!depth)
574  return;
575  // If "Depth" is not provided by the caller, use the return value of
576  // backtrace() for printing a symbolized stack trace.
577  if (!Depth)
578  Depth = depth;
579  if (printSymbolizedStackTrace(Argv0, StackTrace, Depth, OS))
580  return;
581  OS << "Stack dump without symbol names (ensure you have llvm-symbolizer in "
582  "your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point "
583  "to it):\n";
584 #if HAVE_DLFCN_H && HAVE_DLADDR
585  int width = 0;
586  for (int i = 0; i < depth; ++i) {
587  Dl_info dlinfo;
588  dladdr(StackTrace[i], &dlinfo);
589  const char* name = strrchr(dlinfo.dli_fname, '/');
590 
591  int nwidth;
592  if (!name) nwidth = strlen(dlinfo.dli_fname);
593  else nwidth = strlen(name) - 1;
594 
595  if (nwidth > width) width = nwidth;
596  }
597 
598  for (int i = 0; i < depth; ++i) {
599  Dl_info dlinfo;
600  dladdr(StackTrace[i], &dlinfo);
601 
602  OS << format("%-2d", i);
603 
604  const char* name = strrchr(dlinfo.dli_fname, '/');
605  if (!name) OS << format(" %-*s", width, dlinfo.dli_fname);
606  else OS << format(" %-*s", width, name+1);
607 
608  OS << format(" %#0*lx", (int)(sizeof(void*) * 2) + 2,
609  (unsigned long)StackTrace[i]);
610 
611  if (dlinfo.dli_sname != nullptr) {
612  OS << ' ';
613  int res;
614  char* d = itaniumDemangle(dlinfo.dli_sname, nullptr, nullptr, &res);
615  if (!d) OS << dlinfo.dli_sname;
616  else OS << d;
617  free(d);
618 
619  OS << format(" + %tu", (static_cast<const char*>(StackTrace[i])-
620  static_cast<const char*>(dlinfo.dli_saddr)));
621  }
622  OS << '\n';
623  }
624 #elif defined(HAVE_BACKTRACE)
625  backtrace_symbols_fd(StackTrace, Depth, STDERR_FILENO);
626 #endif
627 #endif
628 }
629 
630 static void PrintStackTraceSignalHandler(void *) {
632 }
633 
635 
636 /// When an error signal (such as SIGABRT or SIGSEGV) is delivered to the
637 /// process, print a stack trace and then exit.
639  bool DisableCrashReporting) {
640  ::Argv0 = Argv0;
641 
642  AddSignalHandler(PrintStackTraceSignalHandler, nullptr);
643 
644 #if defined(__APPLE__) && ENABLE_CRASH_OVERRIDES
645  // Environment variable to disable any kind of crash dialog.
646  if (DisableCrashReporting || getenv("LLVM_DISABLE_CRASH_REPORT")) {
647  mach_port_t self = mach_task_self();
648 
649  exception_mask_t mask = EXC_MASK_CRASH;
650 
651  kern_return_t ret = task_set_exception_ports(self,
652  mask,
653  MACH_PORT_NULL,
654  EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES,
655  THREAD_STATE_NONE);
656  (void)ret;
657  }
658 #endif
659 }
i
i
Definition: README.txt:29
MemoryBuffer.h
LLVM_ATTRIBUTE_USED
#define LLVM_ATTRIBUTE_USED
Definition: Compiler.h:144
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
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::ELF::PT_LOAD
@ PT_LOAD
Definition: ELF.h:1284
llvm::AMDGPUISD::IF
@ IF
Definition: AMDGPUISelLowering.h:350
llvm::Depth
@ Depth
Definition: SIMachineScheduler.h:36
llvm::sys::RunSignalHandlers
void RunSignalHandlers()
Definition: Signals.cpp:89
llvm::sys::path::end
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:233
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::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:892
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:56
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:60
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:166
insertSignalHandler
static void insertSignalHandler(sys::SignalHandlerCallback FnPtr, void *Cookie)
Definition: Signals.cpp:104
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:53
llvm::StringRef::str
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:245
llvm::array_lengthof
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLExtras.h:1390
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:135
Index
uint32_t Index
Definition: ELFObjHandler.cpp:84
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:1612
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:59
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:1528
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:78
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::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
llvm::itaniumDemangle
char * itaniumDemangle(const char *mangled_name, char *buf, size_t *n, int *status)
Definition: ItaniumDemangle.cpp:326
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:1263
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...