LLVM 24.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"
42#include "llvm/Support/Format.h"
44#include "llvm/Support/Mutex.h"
48#include <algorithm>
49#include <string>
50#ifdef HAVE_BACKTRACE
51#include BACKTRACE_HEADER // For backtrace().
52#endif
53#include <signal.h>
54#include <sys/stat.h>
55#include <dlfcn.h>
56#if HAVE_MACH_MACH_H
57#include <mach/mach.h>
58#endif
59#ifdef __APPLE__
60#include <mach-o/dyld.h>
61#endif
62#if __has_include(<link.h>)
63#include <link.h>
64#endif
65#ifdef HAVE__UNWIND_BACKTRACE
66// FIXME: We should be able to use <unwind.h> for any target that has an
67// _Unwind_Backtrace function, but on FreeBSD the configure test passes
68// despite the function not existing, and on Android, <unwind.h> conflicts
69// with <link.h>.
70#ifdef __GLIBC__
71#include <unwind.h>
72#else
73#undef HAVE__UNWIND_BACKTRACE
74#endif
75#endif
76#if ENABLE_BACKTRACES && defined(__MVS__)
78#include <__le_cwi.h>
79#endif
80
81#if defined(__linux__)
82#include <sys/syscall.h>
83#endif
84
85using namespace llvm;
86
87static void SignalHandler(int Sig, siginfo_t *Info, void *Context);
88static void SignalHandlerTerminate(int Sig, siginfo_t *Info, void *Context);
89static void InfoSignalHandler(int Sig); // defined below.
90static void InfoSignalHandlerTerminate(int Sig); // defined below.
91
92using SignalHandlerFunctionType = void (*)();
93/// The function to call if ctrl-c is pressed.
94static std::atomic<SignalHandlerFunctionType> InterruptFunction = nullptr;
95static std::atomic<SignalHandlerFunctionType> InfoSignalFunction = nullptr;
96/// The function to call on SIGPIPE (one-time use only).
97static std::atomic<SignalHandlerFunctionType> OneShotPipeSignalFunction =
98 nullptr;
99
100namespace {
101/// Sentinel stored in a node after the signal handler has removed the file;
102/// not a valid path, never freed.
103static char InvalidPathSentinel[] = "\01\02\03\04";
104
105/// Signal-safe removal of files.
106/// Inserting and erasing from the list isn't signal-safe, but removal of files
107/// themselves is signal-safe. Memory is freed when the head is freed, deletion
108/// is therefore not signal-safe either.
109class FileToRemoveList {
110 std::atomic<char *> Filename = nullptr;
111 std::atomic<FileToRemoveList *> Next = nullptr;
112
113 FileToRemoveList() = default;
114 // Takes ownership of \p filename.
115 FileToRemoveList(char *filename) : Filename(filename) {}
116
117public:
118 // Not signal-safe.
119 ~FileToRemoveList() {
120 if (FileToRemoveList *N = Next.exchange(nullptr))
121 delete N;
122 if (char *F = Filename.exchange(nullptr))
123 if (F != InvalidPathSentinel)
124 free(F);
125 }
126
127 // Not signal-safe.
128 static void insert(std::atomic<FileToRemoveList *> &Head,
129 const std::string &Filename) {
130 // Reuse a node with a null filename (left behind by erase) if one exists.
131 // There are two cases where Filename can be special:
132 // - nullptr: a node left behind by a previous file that we had to remove
133 // - InvalidPathSentinel: a node whose file is actively being removed by a
134 // signal handler right now, in which case it's OK if this file doesn't
135 // get removed.
136 char *NewFilename = strdup(Filename.c_str());
137 std::atomic<FileToRemoveList *> *InsertionPoint = &Head;
138 for (FileToRemoveList *Current = Head.load(); Current;
139 Current = Current->Next.load()) {
140 char *NullFilename = nullptr;
141 if (Current->Filename.compare_exchange_strong(NullFilename, NewFilename))
142 return; // Reused a slot.
143 InsertionPoint = &Current->Next;
144 }
145
146 // Append the new node at the end; on CAS failure, advance to the new tail.
147 FileToRemoveList *NewNode = new FileToRemoveList(NewFilename);
148 FileToRemoveList *OldNext = nullptr;
149 while (!InsertionPoint->compare_exchange_strong(OldNext, NewNode)) {
150 InsertionPoint = &OldNext->Next;
151 OldNext = nullptr;
152 }
153 }
154
155 // Not signal-safe.
156 static void erase(std::atomic<FileToRemoveList *> &Head,
157 const std::string &Filename) {
158 // Use a lock to avoid concurrent erase: the comparison would access
159 // free'd memory.
160 static ManagedStatic<sys::SmartMutex<true>> Lock;
161 sys::SmartScopedLock<true> Writer(*Lock);
162
163 for (FileToRemoveList *Current = Head.load(); Current;
164 Current = Current->Next.load()) {
165 if (char *OldFilename = Current->Filename.load()) {
166 if (OldFilename != Filename)
167 continue;
168 // Leave an empty filename. Use CAS to avoid racing with the signal
169 // handler (which can't take the writer lock); only clear and free
170 // if we still own the pointer.
171 char *Expected = OldFilename;
172 while (!Current->Filename.compare_exchange_strong(Expected, nullptr)) {
173 if (Expected == nullptr || Expected == InvalidPathSentinel)
174 break;
175 }
176 if (Expected == OldFilename)
177 free(OldFilename);
178 }
179 }
180 }
181
182 static void removeFile(char *path) {
183 // Get the status so we can determine if it's a file or directory. If we
184 // can't stat the file, ignore it.
185 struct stat buf;
186 if (stat(path, &buf) != 0)
187 return;
188
189 // If this is not a regular file, ignore it. We want to prevent removal
190 // of special files like /dev/null, even if the compiler is being run
191 // with the super-user permissions.
192 if (!S_ISREG(buf.st_mode))
193 return;
194
195 // Otherwise, remove the file. We ignore any errors here as there is
196 // nothing else we can do.
197 unlink(path);
198 }
199
200 // Signal-safe.
201 static void removeAllFiles(std::atomic<FileToRemoveList *> &Head) {
202 // This signal-safe code cannot acquire the writer lock, and needs to defend
203 // against racing writes from the `erase` method above.
204 FileToRemoveList *OldHead = Head.exchange(nullptr);
205
206 for (FileToRemoveList *currentFile = OldHead; currentFile;
207 currentFile = currentFile->Next.load()) {
208 // Take exclusive ownership by swapping in the sentinel (signal-safe: no
209 // allocation or free). Then put the path back so we don't leak.
210 char *Path = currentFile->Filename.exchange(InvalidPathSentinel);
211 if (!Path) {
212 // Restore an empty slot so future insertions can reuse it.
213 currentFile->Filename.exchange(nullptr);
214 } else if (Path != InvalidPathSentinel) {
215 removeFile(Path);
216 // Add the path back to the list to create a global root referencing the
217 // heap allocation, which will pacify leak checkers that run at exit.
218 currentFile->Filename.exchange(Path);
219 }
220 }
221
222 // We're done removing files, cleanup can safely proceed.
223 Head.exchange(OldHead);
224 }
225};
226static std::atomic<FileToRemoveList *> FilesToRemove = nullptr;
227
228/// Clean up the list in a signal-friendly manner.
229/// Recall that signals can fire during llvm_shutdown. If this occurs we should
230/// either clean something up or nothing at all, but we shouldn't crash!
231struct FilesToRemoveCleanup {
232 // Not signal-safe.
233 ~FilesToRemoveCleanup() {
234 FileToRemoveList *Head = FilesToRemove.exchange(nullptr);
235 if (Head)
236 delete Head;
237 }
238};
239} // namespace
240
241static StringRef Argv0;
242
243/// Signals that represent requested termination. There's no bug or failure, or
244/// if there is, it's not our direct responsibility. For whatever reason, our
245/// continued execution is no longer desirable.
246static const int IntSigs[] = {SIGHUP, SIGINT, SIGTERM, SIGUSR2};
247
248/// Signals that represent that we have a bug, and our prompt termination has
249/// been ordered.
250static const int KillSigs[] = {SIGILL,
251 SIGTRAP,
252 SIGABRT,
253 SIGFPE,
254 SIGBUS,
255 SIGSEGV,
256 SIGQUIT
257#ifdef SIGSYS
258 ,
259 SIGSYS
260#endif
261#ifdef SIGXCPU
262 ,
263 SIGXCPU
264#endif
265#ifdef SIGXFSZ
266 ,
267 SIGXFSZ
268#endif
269#ifdef SIGEMT
270 ,
271 SIGEMT
272#endif
273};
274
275/// Signals that represent requests for status.
276static const int InfoSigs[] = {SIGUSR1
277#ifdef SIGINFO
278 ,
279 SIGINFO
280#endif
281};
282
283static const size_t NumSigs = std::size(IntSigs) + std::size(KillSigs) +
284 std::size(InfoSigs) + 1 /* SIGPIPE */;
285
286static std::atomic<unsigned> NumRegisteredSignals = 0;
287static struct {
288 struct sigaction SA;
289 int SigNo;
290} RegisteredSignalInfo[NumSigs];
291
292#if defined(HAVE_SIGALTSTACK)
293// Hold onto both the old and new alternate signal stack so that it's not
294// reported as a leak. We don't make any attempt to remove our alt signal
295// stack if we remove our signal handlers; that can't be done reliably if
296// someone else is also trying to do the same thing.
297static stack_t OldAltStack;
298LLVM_ATTRIBUTE_USED static void *NewAltStackPointer;
299
300static void CreateSigAltStack() {
301 const size_t AltStackSize = MINSIGSTKSZ + 64 * 1024;
302
303 // If we're executing on the alternate stack, or we already have an alternate
304 // signal stack that we're happy with, there's nothing for us to do. Don't
305 // reduce the size, some other part of the process might need a larger stack
306 // than we do.
307 if (sigaltstack(nullptr, &OldAltStack) != 0 ||
308 OldAltStack.ss_flags & SS_ONSTACK ||
309 (OldAltStack.ss_sp && OldAltStack.ss_size >= AltStackSize))
310 return;
311
312 stack_t AltStack = {};
313 AltStack.ss_sp = static_cast<char *>(safe_malloc(AltStackSize));
314 NewAltStackPointer = AltStack.ss_sp; // Save to avoid reporting a leak.
315 AltStack.ss_size = AltStackSize;
316 if (sigaltstack(&AltStack, &OldAltStack) != 0)
317 free(AltStack.ss_sp);
318}
319#else
320static void CreateSigAltStack() {}
321#endif
322
323static void RegisterHandlers(
324 bool NeedsPOSIXUtilitySignalHandling = false) { // Not signal-safe.
325 // The mutex prevents other threads from registering handlers while we're
326 // doing it. We also have to protect the handlers and their count because
327 // a signal handler could fire while we're registering handlers.
328 static ManagedStatic<sys::SmartMutex<true>> SignalHandlerRegistrationMutex;
329 sys::SmartScopedLock<true> Guard(*SignalHandlerRegistrationMutex);
330
331 // If the handlers are already registered, we're done.
332 if (NumRegisteredSignals.load() != 0)
333 return;
334
335 // Create an alternate stack for signal handling. This is necessary for us to
336 // be able to reliably handle signals due to stack overflow.
337 CreateSigAltStack();
338
339 enum class SignalKind { IsKill, IsInfo };
340 auto registerHandler = [&](int Signal, SignalKind Kind) {
341 unsigned Index = NumRegisteredSignals.load();
342 assert(Index < std::size(RegisteredSignalInfo) &&
343 "Out of space for signal handlers!");
344
345 struct sigaction NewHandler;
346
347 switch (Kind) {
348 case SignalKind::IsKill:
349 if (NeedsPOSIXUtilitySignalHandling)
350 // If POSIX signal-handling semantics are followed, the signal handler
351 // resignal itself to terminate after handling the signal.
352 NewHandler.sa_sigaction = SignalHandlerTerminate;
353 else
354 NewHandler.sa_sigaction = SignalHandler;
355 NewHandler.sa_flags = SA_NODEFER | SA_RESETHAND | SA_ONSTACK | SA_SIGINFO;
356 break;
357 case SignalKind::IsInfo:
358 if (NeedsPOSIXUtilitySignalHandling)
359 // If POSIX signal-handling semantics are followed, the signal handler
360 // resignal itself to terminate after handling the signal.
361 NewHandler.sa_handler = InfoSignalHandlerTerminate;
362 else
363 NewHandler.sa_handler = InfoSignalHandler;
364 NewHandler.sa_flags = SA_ONSTACK;
365 break;
366 }
367 sigemptyset(&NewHandler.sa_mask);
368
369 if (NeedsPOSIXUtilitySignalHandling) {
370 // Don't install the new handler if the signal disposition is SIG_IGN.
371 struct sigaction act;
372 if (sigaction(Signal, NULL, &act) == 0 && act.sa_handler != SIG_IGN)
373 sigaction(Signal, &NewHandler, &RegisteredSignalInfo[Index].SA);
374 } else {
375 sigaction(Signal, &NewHandler, &RegisteredSignalInfo[Index].SA);
376 }
377 RegisteredSignalInfo[Index].SigNo = Signal;
378 ++NumRegisteredSignals;
379 };
380
381 for (auto S : IntSigs)
382 registerHandler(S, SignalKind::IsKill);
383 for (auto S : KillSigs)
384 registerHandler(S, SignalKind::IsKill);
385 if (OneShotPipeSignalFunction)
386 registerHandler(SIGPIPE, SignalKind::IsKill);
387 for (auto S : InfoSigs)
388 registerHandler(S, SignalKind::IsInfo);
389}
390
392 // Restore all of the signal handlers to how they were before we showed up.
393 for (unsigned i = 0, e = NumRegisteredSignals.load(); i != e; ++i) {
394 sigaction(RegisteredSignalInfo[i].SigNo, &RegisteredSignalInfo[i].SA,
395 nullptr);
396 --NumRegisteredSignals;
397 }
398}
399
400/// Process the FilesToRemove list.
401static void RemoveFilesToRemove() {
402 FileToRemoveList::removeAllFiles(FilesToRemove);
403}
404
405void sys::CleanupOnSignal(uintptr_t Context) {
406 // Let's not interfere with stack trace symbolication and friends.
407 auto BypassSandbox = sandbox::scopedDisable();
408
409 int Sig = (int)Context;
410
411 if (llvm::is_contained(InfoSigs, Sig)) {
412 InfoSignalHandler(Sig);
413 return;
414 }
415
416 RemoveFilesToRemove();
417
418 if (llvm::is_contained(IntSigs, Sig) || Sig == SIGPIPE)
419 return;
420
422}
423
424// The signal handler that runs.
425static void SignalHandler(int Sig, siginfo_t *Info, void *Context) {
426 // Restore the signal behavior to default, so that the program actually
427 // crashes when we return and the signal reissues. This also ensures that if
428 // we crash in our signal handler that the program will terminate immediately
429 // instead of recursing in the signal handler.
431
432 // Unmask all potentially blocked kill signals.
433 sigset_t SigMask;
434 sigfillset(&SigMask);
435 sigprocmask(SIG_UNBLOCK, &SigMask, nullptr);
436
437 {
438 RemoveFilesToRemove();
439
440 if (Sig == SIGPIPE)
441 if (auto OldOneShotPipeFunction =
442 OneShotPipeSignalFunction.exchange(nullptr))
443 return OldOneShotPipeFunction();
444
445 bool IsIntSig = llvm::is_contained(IntSigs, Sig);
446 if (IsIntSig)
447 if (auto OldInterruptFunction = InterruptFunction.exchange(nullptr))
448 return OldInterruptFunction();
449
450 if (Sig == SIGPIPE || IsIntSig) {
451 raise(Sig); // Execute the default handler.
452 return;
453 }
454 }
455
456 // Otherwise if it is a fault (like SEGV) run any handler.
458
459#ifdef __s390__
460 // On S/390, certain signals are delivered with PSW Address pointing to
461 // *after* the faulting instruction. Simply returning from the signal
462 // handler would continue execution after that point, instead of
463 // re-raising the signal. Raise the signal manually in those cases.
464 if (Sig == SIGILL || Sig == SIGFPE || Sig == SIGTRAP)
465 raise(Sig);
466#endif
467
468#if defined(__linux__)
469 // Re-raising a signal via `raise` loses the original siginfo. Recent versions
470 // of Linux (>= 3.9) support a process sending a signal to itself with
471 // arbitrary signal information using a syscall. If this fails, we fall back
472 // to the `raise` path.
473 int Result =
474 syscall(SYS_rt_tgsigqueueinfo, getpid(), syscall(SYS_gettid), Sig, Info);
475 if (Result == 0)
476 return;
477#endif
478
479 // Was the signal generated by kill(), sigqueue(), etc?
480 bool ReraiseSignal = Info->si_code == SI_QUEUE;
481#if defined(SI_USER)
482 ReraiseSignal |= Info->si_code == SI_USER;
483#endif
484#if defined(SI_LWP)
485 // _lwp_kill() on BSDs, Solaris/illumos, possibly others.
486 ReraiseSignal |= Info->si_code == SI_LWP;
487#endif
488
489#if defined(__APPLE__)
490 // The Darwin kernel elects not to fill out si_code with the SI_* signal
491 // codes...but at least we know that checking si_pid is valid regardless of
492 // si_code on this platform, so this is a decent proxy for answering the above
493 // question. It does unfortunately mean that we don't include signals sent via
494 // those APIs by other threads in the current process.
495 //
496 // si_pid == 0 will be the case for kernel-generated signals (i.e. like
497 // SI_KERNEL on Linux).
498 ReraiseSignal = Info->si_pid != 0 && Info->si_pid != getpid();
499#endif
500
501 // If the signal was explicitly sent, we cannot expect it to trigger again
502 // when we return from the signal handler, so we must re-raise it. The common
503 // case for this will be a signal sent by another process, but it's also
504 // possible that a thread in the current process could have sent the signal.
505 if (ReraiseSignal)
506 raise(Sig);
507}
508
509static void SignalHandlerTerminate(int Sig, siginfo_t *Info, void *Context) {
510 SignalHandler(Sig, Info, Context);
511
512 // Resignal if it is a kill signal so that the exit code contains the
513 // terminating signal number.
514 if (llvm::is_contained(KillSigs, Sig))
515 raise(Sig); // Execute the default handler.
516}
517
518static void InfoSignalHandler(int Sig) {
519 SaveAndRestore SaveErrnoDuringASignalHandler(errno);
520 if (SignalHandlerFunctionType CurrentInfoFunction = InfoSignalFunction)
521 CurrentInfoFunction();
522}
523
524static void InfoSignalHandlerTerminate(int Sig) {
525 InfoSignalHandler(Sig);
526
527 if (Sig == SIGUSR1) {
529 raise(Sig);
530 }
531}
532
534 // Let's not interfere with stack trace symbolication and friends.
535 auto BypassSandbox = sandbox::scopedDisable();
536
537 RemoveFilesToRemove();
538}
539
540void llvm::sys::SetInterruptFunction(void (*IF)()) {
541 InterruptFunction.exchange(IF);
542 RegisterHandlers();
543}
544
545void llvm::sys::SetInfoSignalFunction(void (*Handler)()) {
546 InfoSignalFunction.exchange(Handler);
547 RegisterHandlers();
548}
549
550void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) {
551 OneShotPipeSignalFunction.exchange(Handler);
552 RegisterHandlers();
553}
554
556 // Send a special return code that drivers can check for, from sysexits.h.
557 exit(EX_IOERR);
558}
559
560// The public API
561bool llvm::sys::RemoveFileOnSignal(StringRef Filename, std::string *ErrMsg) {
562 // Ensure that cleanup will occur as soon as one file is added.
563 static ManagedStatic<FilesToRemoveCleanup> FilesToRemoveCleanup;
564 *FilesToRemoveCleanup;
565 FileToRemoveList::insert(FilesToRemove, Filename.str());
566 RegisterHandlers();
567 return false;
568}
569
570// The public API
572 FileToRemoveList::erase(FilesToRemove, Filename.str());
573}
574
575/// Add a function to be called when a signal is delivered to the process. The
576/// handler can have a cookie passed to it to identify what instance of the
577/// handler it is.
579 bool NeedsPOSIXUtilitySignalHandling) {
580 // Signal-safe.
581 insertSignalHandler(FnPtr, Cookie);
582 RegisterHandlers(NeedsPOSIXUtilitySignalHandling);
583}
584
585#if ENABLE_BACKTRACES && defined(HAVE_BACKTRACE) && \
586 (defined(__linux__) || defined(__FreeBSD__) || \
587 defined(__FreeBSD_kernel__) || defined(__NetBSD__) || \
588 defined(__OpenBSD__) || defined(__DragonFly__))
589struct DlIteratePhdrData {
590 void **StackTrace;
591 int depth;
592 bool first;
593 const char **modules;
594 intptr_t *offsets;
595 const char *main_exec_name;
596};
597
598static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
599 DlIteratePhdrData *data = (DlIteratePhdrData *)arg;
600 const char *name = data->first ? data->main_exec_name : info->dlpi_name;
601 data->first = false;
602 for (int i = 0; i < info->dlpi_phnum; i++) {
603 const auto *phdr = &info->dlpi_phdr[i];
604 if (phdr->p_type != PT_LOAD)
605 continue;
606 intptr_t beg = info->dlpi_addr + phdr->p_vaddr;
607 intptr_t end = beg + phdr->p_memsz;
608 for (int j = 0; j < data->depth; j++) {
609 if (data->modules[j])
610 continue;
611 intptr_t addr = (intptr_t)data->StackTrace[j];
612 if (beg <= addr && addr < end) {
613 data->modules[j] = name;
614 data->offsets[j] = addr - info->dlpi_addr;
615 }
616 }
617 }
618 return 0;
619}
620
621#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
622#if !defined(HAVE_BACKTRACE)
623#error DebugLoc origin-tracking currently requires `backtrace()`.
624#endif
625namespace llvm {
626namespace sys {
627template <unsigned long MaxDepth>
628int getStackTrace(std::array<void *, MaxDepth> &StackTrace) {
629 return backtrace(StackTrace.data(), MaxDepth);
630}
631template int getStackTrace<16ul>(std::array<void *, 16ul> &);
632} // namespace sys
633} // namespace llvm
634#endif
635
636/// If this is an ELF platform, we can find all loaded modules and their virtual
637/// addresses with dl_iterate_phdr.
638static bool findModulesAndOffsets(void **StackTrace, int Depth,
639 const char **Modules, intptr_t *Offsets,
640 const char *MainExecutableName,
641 StringSaver &StrPool) {
642 DlIteratePhdrData data = {StackTrace, Depth, true,
643 Modules, Offsets, MainExecutableName};
644 dl_iterate_phdr(dl_iterate_phdr_cb, &data);
645 return true;
646}
647
648class DSOMarkupPrinter {
650 const char *MainExecutableName;
651 size_t ModuleCount = 0;
652 bool IsFirst = true;
653
654public:
655 DSOMarkupPrinter(llvm::raw_ostream &OS, const char *MainExecutableName)
656 : OS(OS), MainExecutableName(MainExecutableName) {}
657
658 /// Print llvm-symbolizer markup describing the layout of the given DSO.
659 void printDSOMarkup(dl_phdr_info *Info) {
660 bool WasFirst = IsFirst;
661 IsFirst = false;
662 ArrayRef<uint8_t> BuildID = findBuildID(Info);
663 if (BuildID.empty())
664 return;
665 OS << format("{{{module:%d:%s:elf:", ModuleCount,
666 WasFirst ? MainExecutableName : Info->dlpi_name);
667 for (uint8_t X : BuildID)
668 OS << format("%02x", X);
669 OS << "}}}\n";
670
671 for (int I = 0; I < Info->dlpi_phnum; I++) {
672 const auto *Phdr = &Info->dlpi_phdr[I];
673 if (Phdr->p_type != PT_LOAD)
674 continue;
675 uintptr_t StartAddress = Info->dlpi_addr + Phdr->p_vaddr;
676 uintptr_t ModuleRelativeAddress = Phdr->p_vaddr;
677 std::array<char, 4> ModeStr = modeStrFromFlags(Phdr->p_flags);
678 OS << format("{{{mmap:%#016x:%#x:load:%d:%s:%#016x}}}\n", StartAddress,
679 Phdr->p_memsz, ModuleCount, &ModeStr[0],
680 ModuleRelativeAddress);
681 }
682 ModuleCount++;
683 }
684
685 /// Callback for use with dl_iterate_phdr. The last dl_iterate_phdr argument
686 /// must be a pointer to an instance of this class.
687 static int printDSOMarkup(dl_phdr_info *Info, size_t Size, void *Arg) {
688 static_cast<DSOMarkupPrinter *>(Arg)->printDSOMarkup(Info);
689 return 0;
690 }
691
692 // Returns the build ID for the given DSO as an array of bytes. Returns an
693 // empty array if none could be found.
694 ArrayRef<uint8_t> findBuildID(dl_phdr_info *Info) {
695 for (int I = 0; I < Info->dlpi_phnum; I++) {
696 const auto *Phdr = &Info->dlpi_phdr[I];
697 if (Phdr->p_type != PT_NOTE)
698 continue;
699
700 ArrayRef<uint8_t> Notes(
701 reinterpret_cast<const uint8_t *>(Info->dlpi_addr + Phdr->p_vaddr),
702 Phdr->p_memsz);
703 while (Notes.size() > 12) {
704 uint32_t NameSize = *reinterpret_cast<const uint32_t *>(Notes.data());
705 Notes = Notes.drop_front(4);
706 uint32_t DescSize = *reinterpret_cast<const uint32_t *>(Notes.data());
707 Notes = Notes.drop_front(4);
708 uint32_t Type = *reinterpret_cast<const uint32_t *>(Notes.data());
709 Notes = Notes.drop_front(4);
710
711 ArrayRef<uint8_t> Name = Notes.take_front(NameSize);
712 auto CurPos = reinterpret_cast<uintptr_t>(Notes.data());
713 uint32_t BytesUntilDesc =
714 alignToPowerOf2(CurPos + NameSize, 4) - CurPos;
715 if (BytesUntilDesc >= Notes.size())
716 break;
717 Notes = Notes.drop_front(BytesUntilDesc);
718
719 ArrayRef<uint8_t> Desc = Notes.take_front(DescSize);
720 CurPos = reinterpret_cast<uintptr_t>(Notes.data());
721 uint32_t BytesUntilNextNote =
722 alignToPowerOf2(CurPos + DescSize, 4) - CurPos;
723 if (BytesUntilNextNote > Notes.size())
724 break;
725 Notes = Notes.drop_front(BytesUntilNextNote);
726
727 if (Type == 3 /*NT_GNU_BUILD_ID*/ && Name.size() >= 3 &&
728 Name[0] == 'G' && Name[1] == 'N' && Name[2] == 'U')
729 return Desc;
730 }
731 }
732 return {};
733 }
734
735 // Returns a symbolizer markup string describing the permissions on a DSO
736 // with the given p_flags.
737 std::array<char, 4> modeStrFromFlags(uint32_t Flags) {
738 std::array<char, 4> Mode;
739 char *Cur = &Mode[0];
740 if (Flags & PF_R)
741 *Cur++ = 'r';
742 if (Flags & PF_W)
743 *Cur++ = 'w';
744 if (Flags & PF_X)
745 *Cur++ = 'x';
746 *Cur = '\0';
747 return Mode;
748 }
749};
750
752 const char *MainExecutableName) {
753 OS << "{{{reset}}}\n";
754 DSOMarkupPrinter MP(OS, MainExecutableName);
755 dl_iterate_phdr(DSOMarkupPrinter::printDSOMarkup, &MP);
756 return true;
757}
758
759#elif ENABLE_BACKTRACES && defined(__APPLE__) && defined(__LP64__)
760static bool findModulesAndOffsets(void **StackTrace, int Depth,
761 const char **Modules, intptr_t *Offsets,
762 const char *MainExecutableName,
763 StringSaver &StrPool) {
764 uint32_t NumImgs = _dyld_image_count();
765 for (uint32_t ImageIndex = 0; ImageIndex < NumImgs; ImageIndex++) {
766 const char *Name = _dyld_get_image_name(ImageIndex);
767 intptr_t Slide = _dyld_get_image_vmaddr_slide(ImageIndex);
768 auto *Header =
769 (const struct mach_header_64 *)_dyld_get_image_header(ImageIndex);
770 if (Header == NULL)
771 continue;
772 auto Cmd = (const struct load_command *)(&Header[1]);
773 for (uint32_t CmdNum = 0; CmdNum < Header->ncmds; ++CmdNum) {
774 uint32_t BaseCmd = Cmd->cmd & ~LC_REQ_DYLD;
775 if (BaseCmd == LC_SEGMENT_64) {
776 auto CmdSeg64 = (const struct segment_command_64 *)Cmd;
777 for (int j = 0; j < Depth; j++) {
778 if (Modules[j])
779 continue;
780 intptr_t Addr = (intptr_t)StackTrace[j];
781 if ((intptr_t)CmdSeg64->vmaddr + Slide <= Addr &&
782 Addr < intptr_t(CmdSeg64->vmaddr + CmdSeg64->vmsize + Slide)) {
783 Modules[j] = Name;
784 Offsets[j] = Addr - Slide;
785 }
786 }
787 }
788 Cmd = (const load_command *)(((const char *)Cmd) + (Cmd->cmdsize));
789 }
790 }
791 return true;
792}
793
795 const char *MainExecutableName) {
796 return false;
797}
798#else
799/// Backtraces are not enabled or we don't yet know how to find all loaded DSOs
800/// on this platform.
801static bool findModulesAndOffsets(void **StackTrace, int Depth,
802 const char **Modules, intptr_t *Offsets,
803 const char *MainExecutableName,
804 StringSaver &StrPool) {
805 return false;
806}
807
809 const char *MainExecutableName) {
810 return false;
811}
812#endif // ENABLE_BACKTRACES && ... (findModulesAndOffsets variants)
813
814#if ENABLE_BACKTRACES && defined(HAVE__UNWIND_BACKTRACE)
815static int unwindBacktrace(void **StackTrace, int MaxEntries) {
816 if (MaxEntries < 0)
817 return 0;
818
819 // Skip the first frame ('unwindBacktrace' itself).
820 int Entries = -1;
821
822 auto HandleFrame = [&](_Unwind_Context *Context) -> _Unwind_Reason_Code {
823 // Apparently we need to detect reaching the end of the stack ourselves.
824 void *IP = (void *)_Unwind_GetIP(Context);
825 if (!IP)
826 return _URC_END_OF_STACK;
827
828 assert(Entries < MaxEntries && "recursively called after END_OF_STACK?");
829 if (Entries >= 0)
830 StackTrace[Entries] = IP;
831
832 if (++Entries == MaxEntries)
833 return _URC_END_OF_STACK;
834 return _URC_NO_REASON;
835 };
836
837 _Unwind_Backtrace(
838 [](_Unwind_Context *Context, void *Handler) {
839 return (*static_cast<decltype(HandleFrame) *>(Handler))(Context);
840 },
841 static_cast<void *>(&HandleFrame));
842 return std::max(Entries, 0);
843}
844#endif
845
846#if ENABLE_BACKTRACES && defined(__MVS__)
847static void zosbacktrace(raw_ostream &OS) {
848 // A function name in the PPA1 can have length 16k.
849 constexpr size_t MAX_ENTRY_NAME = UINT16_MAX;
850 // Limit all other strings to 8 byte.
851 constexpr size_t MAX_OTHER = 8;
852 int32_t dsa_format = -1; // Input/Output
853 void *caaptr = _gtca(); // Input
854 int32_t member_id; // Output
855 char compile_unit_name[MAX_OTHER]; // Output
856 void *compile_unit_address; // Output
857 void *call_instruction_address = nullptr; // Input/Output
858 char entry_name[MAX_ENTRY_NAME]; // Output
859 void *entry_address; // Output
860 void *callers_instruction_address; // Output
861 void *callers_dsaptr; // Output
862 int32_t callers_dsa_format; // Output
863 char statement_id[MAX_OTHER]; // Output
864 void *cibptr; // Output
865 int32_t main_program; // Output
866 _FEEDBACK fc; // Output
867
868 // The DSA pointer is the value of the stack pointer r4.
869 // __builtin_frame_address() returns a pointer to the stack frame, so the
870 // stack bias has to be considered to get the expected DSA value.
871 void *dsaptr = static_cast<char *>(__builtin_frame_address(0)) - 2048;
872 int count = 0;
873 OS << " DSA Adr EP +EP DSA "
874 " Entry\n";
875 while (1) {
876 // After the call, these variables contain the length of the string.
877 int32_t compile_unit_name_length = sizeof(compile_unit_name);
878 int32_t entry_name_length = sizeof(entry_name);
879 int32_t statement_id_length = sizeof(statement_id);
880 // See
881 // https://www.ibm.com/docs/en/zos/3.1.0?topic=cwicsa6a-celqtbck-also-known-as-celqtbck-64-bit-traceback-service
882 // for documentation of the parameters.
883 __CELQTBCK(&dsaptr, &dsa_format, &caaptr, &member_id, &compile_unit_name[0],
884 &compile_unit_name_length, &compile_unit_address,
885 &call_instruction_address, &entry_name[0], &entry_name_length,
886 &entry_address, &callers_instruction_address, &callers_dsaptr,
887 &callers_dsa_format, &statement_id[0], &statement_id_length,
888 &cibptr, &main_program, &fc);
889 if (fc.tok_sev) {
890 OS << format("error: CELQTBCK returned severity %d message %d\n",
891 fc.tok_sev, fc.tok_msgno);
892 break;
893 }
894
895 if (count) { // Omit first entry.
896 uintptr_t diff = reinterpret_cast<uintptr_t>(call_instruction_address) -
897 reinterpret_cast<uintptr_t>(entry_address);
898 OS << format(" %3d. 0x%016lX", count, call_instruction_address);
899 OS << format(" 0x%016lX +0x%08lX 0x%016lX", entry_address, diff, dsaptr);
901 ConverterEBCDIC::convertToUTF8(StringRef(entry_name, entry_name_length),
902 Str);
903 OS << ' ' << Str << '\n';
904 }
905 ++count;
906 if (callers_dsaptr) {
907 dsaptr = callers_dsaptr;
908 dsa_format = callers_dsa_format;
909 call_instruction_address = callers_instruction_address;
910 } else
911 break;
912 }
913}
914#endif
915
916// In the case of a program crash or fault, print out a stack trace so that the
917// user has an indication of why and where we died.
918//
919// On glibc systems we have the 'backtrace' function, which works nicely, but
920// doesn't demangle symbols.
922#if ENABLE_BACKTRACES
923#ifdef __MVS__
924 zosbacktrace(OS);
925#else
926 static void *StackTrace[256];
927 int depth = 0;
928#if defined(HAVE_BACKTRACE)
929 // Use backtrace() to output a backtrace on Linux systems with glibc.
930 if (!depth)
931 depth = backtrace(StackTrace, static_cast<int>(std::size(StackTrace)));
932#endif
933#if defined(HAVE__UNWIND_BACKTRACE)
934 // Try _Unwind_Backtrace() if backtrace() failed.
935 if (!depth)
936 depth =
937 unwindBacktrace(StackTrace, static_cast<int>(std::size(StackTrace)));
938#endif
939 if (!depth)
940 return;
941 // If "Depth" is not provided by the caller, use the return value of
942 // backtrace() for printing a symbolized stack trace.
943 if (!Depth)
944 Depth = depth;
945 if (printMarkupStackTrace(Argv0, StackTrace, Depth, OS))
946 return;
947 if (printSymbolizedStackTrace(Argv0, StackTrace, Depth, OS))
948 return;
949 OS << "Stack dump without symbol names (ensure you have llvm-symbolizer in "
950 "your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point "
951 "to it):\n";
952#if HAVE_DLOPEN && !defined(_AIX)
953 int width = 0;
954 for (int i = 0; i < depth; ++i) {
955 Dl_info dlinfo;
956 int nwidth;
957 if (dladdr(StackTrace[i], &dlinfo) == 0) {
958 nwidth = 7; // "(error)"
959 } else {
960 const char *name = strrchr(dlinfo.dli_fname, '/');
961
962 if (!name)
963 nwidth = strlen(dlinfo.dli_fname);
964 else
965 nwidth = strlen(name) - 1;
966 }
967
968 width = std::max(nwidth, width);
969 }
970
971 for (int i = 0; i < depth; ++i) {
972 Dl_info dlinfo;
973
974 OS << format("%-2d", i);
975
976 if (dladdr(StackTrace[i], &dlinfo) == 0) {
977 OS << format(" %-*s", width, static_cast<const char *>("(error)"));
978 dlinfo.dli_sname = nullptr;
979 } else {
980 const char *name = strrchr(dlinfo.dli_fname, '/');
981 if (!name)
982 OS << format(" %-*s", width, dlinfo.dli_fname);
983 else
984 OS << format(" %-*s", width, name + 1);
985 }
986
987 OS << format(" %#0*lx", (int)(sizeof(void *) * 2) + 2,
988 (unsigned long)StackTrace[i]);
989
990 if (dlinfo.dli_sname != nullptr) {
991 OS << ' ';
992 if (char *d = itaniumDemangle(dlinfo.dli_sname)) {
993 OS << d;
994 free(d);
995 } else {
996 OS << dlinfo.dli_sname;
997 }
998
999 OS << format(" + %tu", (static_cast<const char *>(StackTrace[i]) -
1000 static_cast<const char *>(dlinfo.dli_saddr)));
1001 }
1002 OS << '\n';
1003 }
1004#elif defined(HAVE_BACKTRACE)
1005 backtrace_symbols_fd(StackTrace, Depth, STDERR_FILENO);
1006#endif
1007#endif
1008#endif
1009}
1010
1011static void PrintStackTraceSignalHandler(void *) {
1013}
1014
1016
1017/// When an error signal (such as SIGABRT or SIGSEGV) is delivered to the
1018/// process, print a stack trace and then exit.
1020 bool DisableCrashReporting) {
1021 ::Argv0 = Argv0;
1022
1023 AddSignalHandler(PrintStackTraceSignalHandler, nullptr);
1024
1025#if defined(__APPLE__) && ENABLE_CRASH_OVERRIDES
1026 // Environment variable to disable any kind of crash dialog.
1027 if (DisableCrashReporting || getenv("LLVM_DISABLE_CRASH_REPORT")) {
1028 mach_port_t self = mach_task_self();
1029
1030 exception_mask_t mask = EXC_MASK_CRASH;
1031
1032 kern_return_t ret = task_set_exception_ports(
1033 self, mask, MACH_PORT_NULL,
1034 EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
1035 (void)ret;
1036 }
1037#endif
1038}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
static constexpr unsigned long long mask(BlockVerifier::State S)
#define LLVM_ATTRIBUTE_USED
Definition Compiler.h:238
This file provides utility functions for converting between EBCDIC-1047 and UTF-8.
This file contains definitions of exit codes for exit() function.
#define STDERR_FILENO
Definition InitLLVM.cpp:31
lazy value info
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
static constexpr StringLiteral Filename
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file contains some templates that are useful if you are working with the STL at all.
static const char * name
This file provides utility classes that use RAII to save and restore values.
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:263
static bool findModulesAndOffsets(void **StackTrace, int Depth, const char **Modules, intptr_t *Offsets, const char *MainExecutableName, StringSaver &StrPool)
static bool printMarkupContext(raw_ostream &OS, const char *MainExecutableName)
static LLVM_ATTRIBUTE_USED bool printMarkupStackTrace(StringRef Argv0, void **StackTrace, int Depth, raw_ostream &OS)
Definition Signals.cpp:343
static void insertSignalHandler(sys::SignalHandlerCallback FnPtr, void *Cookie)
Definition Signals.cpp:115
static Split data
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
Definition StringSaver.h:22
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
LLVM_ABI void convertToUTF8(StringRef Source, SmallVectorImpl< char > &Result)
Offsets
Offsets in bytes from the start of the input buffer.
constexpr size_t NameSize
Definition XCOFF.h:30
SmallVector< uint8_t, 10 > BuildID
A build ID in binary form.
Definition BuildID.h:27
iterator end() const
Definition BasicBlock.h:89
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
Definition Path.cpp:594
ScopedSetting scopedDisable()
Definition IOSandbox.h:36
std::lock_guard< SmartMutex< mt_only > > SmartScopedLock
Definition Mutex.h:69
LLVM_ABI void DefaultOneShotPipeSignalHandler()
On Unix systems and Windows, this function exits with an "IO error" exit code.
LLVM_ABI void PrintStackTrace(raw_ostream &OS, int Depth=0)
Print the stack trace using the given raw_ostream object.
LLVM_ABI void DisableSystemDialogsOnCrash()
Disable all system dialog boxes that appear when the process crashes.
LLVM_ABI void unregisterHandlers()
LLVM_ABI void DontRemoveFileOnSignal(StringRef Filename)
This function removes a file from the list of files to be removed on signal delivery.
LLVM_ABI void AddSignalHandler(SignalHandlerCallback FnPtr, void *Cookie, bool NeedsPOSIXUtilitySignalHandling=false)
Add a function to be called when an abort/kill signal is delivered to the process.
LLVM_ABI 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_ABI void SetInfoSignalFunction(void(*Handler)())
Registers a function to be called when an "info" signal is delivered to the process.
LLVM_ABI void SetOneShotPipeSignalFunction(void(*Handler)())
Registers a function to be called in a "one-shot" manner when a pipe signal is delivered to the proce...
LLVM_ABI void SetInterruptFunction(void(*IF)())
This function registers a function to be called when the user "interrupts" the program (typically by ...
LLVM_ABI void RunSignalHandlers()
Definition Signals.cpp:98
LLVM_ABI void CleanupOnSignal(uintptr_t Context)
This function does the following:
LLVM_ABI void RunInterruptHandlers()
This function runs all the registered interrupt handlers, including the removal of files registered b...
LLVM_ABI 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...
void(*)(void *) SignalHandlerCallback
Definition Signals.h:98
This is an optimization pass for GlobalISel generic memory operations.
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:1669
Op::Description Desc
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
Definition STLExtras.h:2200
DEMANGLE_ABI char * itaniumDemangle(std::string_view mangled_name, bool ParseParams=true)
Returns a non-NULL pointer to a NUL-terminated C style string that should be explicitly freed,...
constexpr T alignToPowerOf2(U Value, V Align)
Will overflow only if result is not representable in T.
Definition MathExtras.h:494
LLVM_ATTRIBUTE_RETURNS_NONNULL void * safe_malloc(size_t Sz)
Definition MemAlloc.h:25
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:102
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
Definition STLExtras.h:2012
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1947
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
Definition InstrProf.h:147
#define N
A utility class that uses RAII to save and restore the value of a variable.