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_USER || Info->si_code == SI_QUEUE;
481#if defined(SI_LWP)
482 // _lwp_kill() on BSDs, Solaris/illumos, possibly others.
483 ReraiseSignal |= Info->si_code == SI_LWP;
484#endif
485
486#if defined(__APPLE__)
487 // The Darwin kernel elects not to fill out si_code with the SI_* signal
488 // codes...but at least we know that checking si_pid is valid regardless of
489 // si_code on this platform, so this is a decent proxy for answering the above
490 // question. It does unfortunately mean that we don't include signals sent via
491 // those APIs by other threads in the current process.
492 //
493 // si_pid == 0 will be the case for kernel-generated signals (i.e. like
494 // SI_KERNEL on Linux).
495 ReraiseSignal = Info->si_pid != 0 && Info->si_pid != getpid();
496#endif
497
498 // If the signal was explicitly sent, we cannot expect it to trigger again
499 // when we return from the signal handler, so we must re-raise it. The common
500 // case for this will be a signal sent by another process, but it's also
501 // possible that a thread in the current process could have sent the signal.
502 if (ReraiseSignal)
503 raise(Sig);
504}
505
506static void SignalHandlerTerminate(int Sig, siginfo_t *Info, void *Context) {
507 SignalHandler(Sig, Info, Context);
508
509 // Resignal if it is a kill signal so that the exit code contains the
510 // terminating signal number.
511 if (llvm::is_contained(KillSigs, Sig))
512 raise(Sig); // Execute the default handler.
513}
514
515static void InfoSignalHandler(int Sig) {
516 SaveAndRestore SaveErrnoDuringASignalHandler(errno);
517 if (SignalHandlerFunctionType CurrentInfoFunction = InfoSignalFunction)
518 CurrentInfoFunction();
519}
520
521static void InfoSignalHandlerTerminate(int Sig) {
522 InfoSignalHandler(Sig);
523
524 if (Sig == SIGUSR1) {
526 raise(Sig);
527 }
528}
529
531 // Let's not interfere with stack trace symbolication and friends.
532 auto BypassSandbox = sandbox::scopedDisable();
533
534 RemoveFilesToRemove();
535}
536
537void llvm::sys::SetInterruptFunction(void (*IF)()) {
538 InterruptFunction.exchange(IF);
539 RegisterHandlers();
540}
541
542void llvm::sys::SetInfoSignalFunction(void (*Handler)()) {
543 InfoSignalFunction.exchange(Handler);
544 RegisterHandlers();
545}
546
547void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) {
548 OneShotPipeSignalFunction.exchange(Handler);
549 RegisterHandlers();
550}
551
553 // Send a special return code that drivers can check for, from sysexits.h.
554 exit(EX_IOERR);
555}
556
557// The public API
558bool llvm::sys::RemoveFileOnSignal(StringRef Filename, std::string *ErrMsg) {
559 // Ensure that cleanup will occur as soon as one file is added.
560 static ManagedStatic<FilesToRemoveCleanup> FilesToRemoveCleanup;
561 *FilesToRemoveCleanup;
562 FileToRemoveList::insert(FilesToRemove, Filename.str());
563 RegisterHandlers();
564 return false;
565}
566
567// The public API
569 FileToRemoveList::erase(FilesToRemove, Filename.str());
570}
571
572/// Add a function to be called when a signal is delivered to the process. The
573/// handler can have a cookie passed to it to identify what instance of the
574/// handler it is.
576 bool NeedsPOSIXUtilitySignalHandling) {
577 // Signal-safe.
578 insertSignalHandler(FnPtr, Cookie);
579 RegisterHandlers(NeedsPOSIXUtilitySignalHandling);
580}
581
582#if ENABLE_BACKTRACES && defined(HAVE_BACKTRACE) && \
583 (defined(__linux__) || defined(__FreeBSD__) || \
584 defined(__FreeBSD_kernel__) || defined(__NetBSD__) || \
585 defined(__OpenBSD__) || defined(__DragonFly__))
586struct DlIteratePhdrData {
587 void **StackTrace;
588 int depth;
589 bool first;
590 const char **modules;
591 intptr_t *offsets;
592 const char *main_exec_name;
593};
594
595static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
596 DlIteratePhdrData *data = (DlIteratePhdrData *)arg;
597 const char *name = data->first ? data->main_exec_name : info->dlpi_name;
598 data->first = false;
599 for (int i = 0; i < info->dlpi_phnum; i++) {
600 const auto *phdr = &info->dlpi_phdr[i];
601 if (phdr->p_type != PT_LOAD)
602 continue;
603 intptr_t beg = info->dlpi_addr + phdr->p_vaddr;
604 intptr_t end = beg + phdr->p_memsz;
605 for (int j = 0; j < data->depth; j++) {
606 if (data->modules[j])
607 continue;
608 intptr_t addr = (intptr_t)data->StackTrace[j];
609 if (beg <= addr && addr < end) {
610 data->modules[j] = name;
611 data->offsets[j] = addr - info->dlpi_addr;
612 }
613 }
614 }
615 return 0;
616}
617
618#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
619#if !defined(HAVE_BACKTRACE)
620#error DebugLoc origin-tracking currently requires `backtrace()`.
621#endif
622namespace llvm {
623namespace sys {
624template <unsigned long MaxDepth>
625int getStackTrace(std::array<void *, MaxDepth> &StackTrace) {
626 return backtrace(StackTrace.data(), MaxDepth);
627}
628template int getStackTrace<16ul>(std::array<void *, 16ul> &);
629} // namespace sys
630} // namespace llvm
631#endif
632
633/// If this is an ELF platform, we can find all loaded modules and their virtual
634/// addresses with dl_iterate_phdr.
635static bool findModulesAndOffsets(void **StackTrace, int Depth,
636 const char **Modules, intptr_t *Offsets,
637 const char *MainExecutableName,
638 StringSaver &StrPool) {
639 DlIteratePhdrData data = {StackTrace, Depth, true,
640 Modules, Offsets, MainExecutableName};
641 dl_iterate_phdr(dl_iterate_phdr_cb, &data);
642 return true;
643}
644
645class DSOMarkupPrinter {
647 const char *MainExecutableName;
648 size_t ModuleCount = 0;
649 bool IsFirst = true;
650
651public:
652 DSOMarkupPrinter(llvm::raw_ostream &OS, const char *MainExecutableName)
653 : OS(OS), MainExecutableName(MainExecutableName) {}
654
655 /// Print llvm-symbolizer markup describing the layout of the given DSO.
656 void printDSOMarkup(dl_phdr_info *Info) {
657 bool WasFirst = IsFirst;
658 IsFirst = false;
659 ArrayRef<uint8_t> BuildID = findBuildID(Info);
660 if (BuildID.empty())
661 return;
662 OS << format("{{{module:%d:%s:elf:", ModuleCount,
663 WasFirst ? MainExecutableName : Info->dlpi_name);
664 for (uint8_t X : BuildID)
665 OS << format("%02x", X);
666 OS << "}}}\n";
667
668 for (int I = 0; I < Info->dlpi_phnum; I++) {
669 const auto *Phdr = &Info->dlpi_phdr[I];
670 if (Phdr->p_type != PT_LOAD)
671 continue;
672 uintptr_t StartAddress = Info->dlpi_addr + Phdr->p_vaddr;
673 uintptr_t ModuleRelativeAddress = Phdr->p_vaddr;
674 std::array<char, 4> ModeStr = modeStrFromFlags(Phdr->p_flags);
675 OS << format("{{{mmap:%#016x:%#x:load:%d:%s:%#016x}}}\n", StartAddress,
676 Phdr->p_memsz, ModuleCount, &ModeStr[0],
677 ModuleRelativeAddress);
678 }
679 ModuleCount++;
680 }
681
682 /// Callback for use with dl_iterate_phdr. The last dl_iterate_phdr argument
683 /// must be a pointer to an instance of this class.
684 static int printDSOMarkup(dl_phdr_info *Info, size_t Size, void *Arg) {
685 static_cast<DSOMarkupPrinter *>(Arg)->printDSOMarkup(Info);
686 return 0;
687 }
688
689 // Returns the build ID for the given DSO as an array of bytes. Returns an
690 // empty array if none could be found.
691 ArrayRef<uint8_t> findBuildID(dl_phdr_info *Info) {
692 for (int I = 0; I < Info->dlpi_phnum; I++) {
693 const auto *Phdr = &Info->dlpi_phdr[I];
694 if (Phdr->p_type != PT_NOTE)
695 continue;
696
697 ArrayRef<uint8_t> Notes(
698 reinterpret_cast<const uint8_t *>(Info->dlpi_addr + Phdr->p_vaddr),
699 Phdr->p_memsz);
700 while (Notes.size() > 12) {
701 uint32_t NameSize = *reinterpret_cast<const uint32_t *>(Notes.data());
702 Notes = Notes.drop_front(4);
703 uint32_t DescSize = *reinterpret_cast<const uint32_t *>(Notes.data());
704 Notes = Notes.drop_front(4);
705 uint32_t Type = *reinterpret_cast<const uint32_t *>(Notes.data());
706 Notes = Notes.drop_front(4);
707
708 ArrayRef<uint8_t> Name = Notes.take_front(NameSize);
709 auto CurPos = reinterpret_cast<uintptr_t>(Notes.data());
710 uint32_t BytesUntilDesc =
711 alignToPowerOf2(CurPos + NameSize, 4) - CurPos;
712 if (BytesUntilDesc >= Notes.size())
713 break;
714 Notes = Notes.drop_front(BytesUntilDesc);
715
716 ArrayRef<uint8_t> Desc = Notes.take_front(DescSize);
717 CurPos = reinterpret_cast<uintptr_t>(Notes.data());
718 uint32_t BytesUntilNextNote =
719 alignToPowerOf2(CurPos + DescSize, 4) - CurPos;
720 if (BytesUntilNextNote > Notes.size())
721 break;
722 Notes = Notes.drop_front(BytesUntilNextNote);
723
724 if (Type == 3 /*NT_GNU_BUILD_ID*/ && Name.size() >= 3 &&
725 Name[0] == 'G' && Name[1] == 'N' && Name[2] == 'U')
726 return Desc;
727 }
728 }
729 return {};
730 }
731
732 // Returns a symbolizer markup string describing the permissions on a DSO
733 // with the given p_flags.
734 std::array<char, 4> modeStrFromFlags(uint32_t Flags) {
735 std::array<char, 4> Mode;
736 char *Cur = &Mode[0];
737 if (Flags & PF_R)
738 *Cur++ = 'r';
739 if (Flags & PF_W)
740 *Cur++ = 'w';
741 if (Flags & PF_X)
742 *Cur++ = 'x';
743 *Cur = '\0';
744 return Mode;
745 }
746};
747
749 const char *MainExecutableName) {
750 OS << "{{{reset}}}\n";
751 DSOMarkupPrinter MP(OS, MainExecutableName);
752 dl_iterate_phdr(DSOMarkupPrinter::printDSOMarkup, &MP);
753 return true;
754}
755
756#elif ENABLE_BACKTRACES && defined(__APPLE__) && defined(__LP64__)
757static bool findModulesAndOffsets(void **StackTrace, int Depth,
758 const char **Modules, intptr_t *Offsets,
759 const char *MainExecutableName,
760 StringSaver &StrPool) {
761 uint32_t NumImgs = _dyld_image_count();
762 for (uint32_t ImageIndex = 0; ImageIndex < NumImgs; ImageIndex++) {
763 const char *Name = _dyld_get_image_name(ImageIndex);
764 intptr_t Slide = _dyld_get_image_vmaddr_slide(ImageIndex);
765 auto *Header =
766 (const struct mach_header_64 *)_dyld_get_image_header(ImageIndex);
767 if (Header == NULL)
768 continue;
769 auto Cmd = (const struct load_command *)(&Header[1]);
770 for (uint32_t CmdNum = 0; CmdNum < Header->ncmds; ++CmdNum) {
771 uint32_t BaseCmd = Cmd->cmd & ~LC_REQ_DYLD;
772 if (BaseCmd == LC_SEGMENT_64) {
773 auto CmdSeg64 = (const struct segment_command_64 *)Cmd;
774 for (int j = 0; j < Depth; j++) {
775 if (Modules[j])
776 continue;
777 intptr_t Addr = (intptr_t)StackTrace[j];
778 if ((intptr_t)CmdSeg64->vmaddr + Slide <= Addr &&
779 Addr < intptr_t(CmdSeg64->vmaddr + CmdSeg64->vmsize + Slide)) {
780 Modules[j] = Name;
781 Offsets[j] = Addr - Slide;
782 }
783 }
784 }
785 Cmd = (const load_command *)(((const char *)Cmd) + (Cmd->cmdsize));
786 }
787 }
788 return true;
789}
790
792 const char *MainExecutableName) {
793 return false;
794}
795#else
796/// Backtraces are not enabled or we don't yet know how to find all loaded DSOs
797/// on this platform.
798static bool findModulesAndOffsets(void **StackTrace, int Depth,
799 const char **Modules, intptr_t *Offsets,
800 const char *MainExecutableName,
801 StringSaver &StrPool) {
802 return false;
803}
804
806 const char *MainExecutableName) {
807 return false;
808}
809#endif // ENABLE_BACKTRACES && ... (findModulesAndOffsets variants)
810
811#if ENABLE_BACKTRACES && defined(HAVE__UNWIND_BACKTRACE)
812static int unwindBacktrace(void **StackTrace, int MaxEntries) {
813 if (MaxEntries < 0)
814 return 0;
815
816 // Skip the first frame ('unwindBacktrace' itself).
817 int Entries = -1;
818
819 auto HandleFrame = [&](_Unwind_Context *Context) -> _Unwind_Reason_Code {
820 // Apparently we need to detect reaching the end of the stack ourselves.
821 void *IP = (void *)_Unwind_GetIP(Context);
822 if (!IP)
823 return _URC_END_OF_STACK;
824
825 assert(Entries < MaxEntries && "recursively called after END_OF_STACK?");
826 if (Entries >= 0)
827 StackTrace[Entries] = IP;
828
829 if (++Entries == MaxEntries)
830 return _URC_END_OF_STACK;
831 return _URC_NO_REASON;
832 };
833
834 _Unwind_Backtrace(
835 [](_Unwind_Context *Context, void *Handler) {
836 return (*static_cast<decltype(HandleFrame) *>(Handler))(Context);
837 },
838 static_cast<void *>(&HandleFrame));
839 return std::max(Entries, 0);
840}
841#endif
842
843#if ENABLE_BACKTRACES && defined(__MVS__)
844static void zosbacktrace(raw_ostream &OS) {
845 // A function name in the PPA1 can have length 16k.
846 constexpr size_t MAX_ENTRY_NAME = UINT16_MAX;
847 // Limit all other strings to 8 byte.
848 constexpr size_t MAX_OTHER = 8;
849 int32_t dsa_format = -1; // Input/Output
850 void *caaptr = _gtca(); // Input
851 int32_t member_id; // Output
852 char compile_unit_name[MAX_OTHER]; // Output
853 void *compile_unit_address; // Output
854 void *call_instruction_address = nullptr; // Input/Output
855 char entry_name[MAX_ENTRY_NAME]; // Output
856 void *entry_address; // Output
857 void *callers_instruction_address; // Output
858 void *callers_dsaptr; // Output
859 int32_t callers_dsa_format; // Output
860 char statement_id[MAX_OTHER]; // Output
861 void *cibptr; // Output
862 int32_t main_program; // Output
863 _FEEDBACK fc; // Output
864
865 // The DSA pointer is the value of the stack pointer r4.
866 // __builtin_frame_address() returns a pointer to the stack frame, so the
867 // stack bias has to be considered to get the expected DSA value.
868 void *dsaptr = static_cast<char *>(__builtin_frame_address(0)) - 2048;
869 int count = 0;
870 OS << " DSA Adr EP +EP DSA "
871 " Entry\n";
872 while (1) {
873 // After the call, these variables contain the length of the string.
874 int32_t compile_unit_name_length = sizeof(compile_unit_name);
875 int32_t entry_name_length = sizeof(entry_name);
876 int32_t statement_id_length = sizeof(statement_id);
877 // See
878 // https://www.ibm.com/docs/en/zos/3.1.0?topic=cwicsa6a-celqtbck-also-known-as-celqtbck-64-bit-traceback-service
879 // for documentation of the parameters.
880 __CELQTBCK(&dsaptr, &dsa_format, &caaptr, &member_id, &compile_unit_name[0],
881 &compile_unit_name_length, &compile_unit_address,
882 &call_instruction_address, &entry_name[0], &entry_name_length,
883 &entry_address, &callers_instruction_address, &callers_dsaptr,
884 &callers_dsa_format, &statement_id[0], &statement_id_length,
885 &cibptr, &main_program, &fc);
886 if (fc.tok_sev) {
887 OS << format("error: CELQTBCK returned severity %d message %d\n",
888 fc.tok_sev, fc.tok_msgno);
889 break;
890 }
891
892 if (count) { // Omit first entry.
893 uintptr_t diff = reinterpret_cast<uintptr_t>(call_instruction_address) -
894 reinterpret_cast<uintptr_t>(entry_address);
895 OS << format(" %3d. 0x%016lX", count, call_instruction_address);
896 OS << format(" 0x%016lX +0x%08lX 0x%016lX", entry_address, diff, dsaptr);
898 ConverterEBCDIC::convertToUTF8(StringRef(entry_name, entry_name_length),
899 Str);
900 OS << ' ' << Str << '\n';
901 }
902 ++count;
903 if (callers_dsaptr) {
904 dsaptr = callers_dsaptr;
905 dsa_format = callers_dsa_format;
906 call_instruction_address = callers_instruction_address;
907 } else
908 break;
909 }
910}
911#endif
912
913// In the case of a program crash or fault, print out a stack trace so that the
914// user has an indication of why and where we died.
915//
916// On glibc systems we have the 'backtrace' function, which works nicely, but
917// doesn't demangle symbols.
919#if ENABLE_BACKTRACES
920#ifdef __MVS__
921 zosbacktrace(OS);
922#else
923 static void *StackTrace[256];
924 int depth = 0;
925#if defined(HAVE_BACKTRACE)
926 // Use backtrace() to output a backtrace on Linux systems with glibc.
927 if (!depth)
928 depth = backtrace(StackTrace, static_cast<int>(std::size(StackTrace)));
929#endif
930#if defined(HAVE__UNWIND_BACKTRACE)
931 // Try _Unwind_Backtrace() if backtrace() failed.
932 if (!depth)
933 depth =
934 unwindBacktrace(StackTrace, static_cast<int>(std::size(StackTrace)));
935#endif
936 if (!depth)
937 return;
938 // If "Depth" is not provided by the caller, use the return value of
939 // backtrace() for printing a symbolized stack trace.
940 if (!Depth)
941 Depth = depth;
942 if (printMarkupStackTrace(Argv0, StackTrace, Depth, OS))
943 return;
944 if (printSymbolizedStackTrace(Argv0, StackTrace, Depth, OS))
945 return;
946 OS << "Stack dump without symbol names (ensure you have llvm-symbolizer in "
947 "your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point "
948 "to it):\n";
949#if HAVE_DLOPEN && !defined(_AIX)
950 int width = 0;
951 for (int i = 0; i < depth; ++i) {
952 Dl_info dlinfo;
953 int nwidth;
954 if (dladdr(StackTrace[i], &dlinfo) == 0) {
955 nwidth = 7; // "(error)"
956 } else {
957 const char *name = strrchr(dlinfo.dli_fname, '/');
958
959 if (!name)
960 nwidth = strlen(dlinfo.dli_fname);
961 else
962 nwidth = strlen(name) - 1;
963 }
964
965 width = std::max(nwidth, width);
966 }
967
968 for (int i = 0; i < depth; ++i) {
969 Dl_info dlinfo;
970
971 OS << format("%-2d", i);
972
973 if (dladdr(StackTrace[i], &dlinfo) == 0) {
974 OS << format(" %-*s", width, static_cast<const char *>("(error)"));
975 dlinfo.dli_sname = nullptr;
976 } else {
977 const char *name = strrchr(dlinfo.dli_fname, '/');
978 if (!name)
979 OS << format(" %-*s", width, dlinfo.dli_fname);
980 else
981 OS << format(" %-*s", width, name + 1);
982 }
983
984 OS << format(" %#0*lx", (int)(sizeof(void *) * 2) + 2,
985 (unsigned long)StackTrace[i]);
986
987 if (dlinfo.dli_sname != nullptr) {
988 OS << ' ';
989 if (char *d = itaniumDemangle(dlinfo.dli_sname)) {
990 OS << d;
991 free(d);
992 } else {
993 OS << dlinfo.dli_sname;
994 }
995
996 OS << format(" + %tu", (static_cast<const char *>(StackTrace[i]) -
997 static_cast<const char *>(dlinfo.dli_saddr)));
998 }
999 OS << '\n';
1000 }
1001#elif defined(HAVE_BACKTRACE)
1002 backtrace_symbols_fd(StackTrace, Depth, STDERR_FILENO);
1003#endif
1004#endif
1005#endif
1006}
1007
1008static void PrintStackTraceSignalHandler(void *) {
1010}
1011
1013
1014/// When an error signal (such as SIGABRT or SIGSEGV) is delivered to the
1015/// process, print a stack trace and then exit.
1017 bool DisableCrashReporting) {
1018 ::Argv0 = Argv0;
1019
1020 AddSignalHandler(PrintStackTraceSignalHandler, nullptr);
1021
1022#if defined(__APPLE__) && ENABLE_CRASH_OVERRIDES
1023 // Environment variable to disable any kind of crash dialog.
1024 if (DisableCrashReporting || getenv("LLVM_DISABLE_CRASH_REPORT")) {
1025 mach_port_t self = mach_task_self();
1026
1027 exception_mask_t mask = EXC_MASK_CRASH;
1028
1029 kern_return_t ret = task_set_exception_ports(
1030 self, mask, MACH_PORT_NULL,
1031 EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
1032 (void)ret;
1033 }
1034#endif
1035}
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:94
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.