LLVM 23.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/// Signal-safe removal of files.
102/// Inserting and erasing from the list isn't signal-safe, but removal of files
103/// themselves is signal-safe. Memory is freed when the head is freed, deletion
104/// is therefore not signal-safe either.
105class FileToRemoveList {
106 std::atomic<char *> Filename = nullptr;
107 std::atomic<FileToRemoveList *> Next = nullptr;
108
109 FileToRemoveList() = default;
110 // Not signal-safe.
111 FileToRemoveList(const std::string &str) : Filename(strdup(str.c_str())) {}
112
113public:
114 // Not signal-safe.
115 ~FileToRemoveList() {
116 if (FileToRemoveList *N = Next.exchange(nullptr))
117 delete N;
118 if (char *F = Filename.exchange(nullptr))
119 free(F);
120 }
121
122 // Not signal-safe.
123 static void insert(std::atomic<FileToRemoveList *> &Head,
124 const std::string &Filename) {
125 // Insert the new file at the end of the list.
126 FileToRemoveList *NewHead = new FileToRemoveList(Filename);
127 std::atomic<FileToRemoveList *> *InsertionPoint = &Head;
128 FileToRemoveList *OldHead = nullptr;
129 while (!InsertionPoint->compare_exchange_strong(OldHead, NewHead)) {
130 InsertionPoint = &OldHead->Next;
131 OldHead = nullptr;
132 }
133 }
134
135 // Not signal-safe.
136 static void erase(std::atomic<FileToRemoveList *> &Head,
137 const std::string &Filename) {
138 // Use a lock to avoid concurrent erase: the comparison would access
139 // free'd memory.
140 static ManagedStatic<sys::SmartMutex<true>> Lock;
141 sys::SmartScopedLock<true> Writer(*Lock);
142
143 for (FileToRemoveList *Current = Head.load(); Current;
144 Current = Current->Next.load()) {
145 if (char *OldFilename = Current->Filename.load()) {
146 if (OldFilename != Filename)
147 continue;
148 // Leave an empty filename.
149 OldFilename = Current->Filename.exchange(nullptr);
150 // The filename might have become null between the time we
151 // compared it and we exchanged it.
152 if (OldFilename)
153 free(OldFilename);
154 }
155 }
156 }
157
158 static void removeFile(char *path) {
159 // Get the status so we can determine if it's a file or directory. If we
160 // can't stat the file, ignore it.
161 struct stat buf;
162 if (stat(path, &buf) != 0)
163 return;
164
165 // If this is not a regular file, ignore it. We want to prevent removal
166 // of special files like /dev/null, even if the compiler is being run
167 // with the super-user permissions.
168 if (!S_ISREG(buf.st_mode))
169 return;
170
171 // Otherwise, remove the file. We ignore any errors here as there is
172 // nothing else we can do.
173 unlink(path);
174 }
175
176 // Signal-safe.
177 static void removeAllFiles(std::atomic<FileToRemoveList *> &Head) {
178 // If cleanup were to occur while we're removing files we'd have a bad time.
179 // Make sure we're OK by preventing cleanup from doing anything while we're
180 // removing files. If cleanup races with us and we win we'll have a leak,
181 // but we won't crash.
182 FileToRemoveList *OldHead = Head.exchange(nullptr);
183
184 for (FileToRemoveList *currentFile = OldHead; currentFile;
185 currentFile = currentFile->Next.load()) {
186 // If erasing was occuring while we're trying to remove files we'd look
187 // at free'd data. Take away the path and put it back when done.
188 if (char *path = currentFile->Filename.exchange(nullptr)) {
189 removeFile(path);
190
191 // We're done removing the file, erasing can safely proceed.
192 currentFile->Filename.exchange(path);
193 }
194 }
195
196 // We're done removing files, cleanup can safely proceed.
197 Head.exchange(OldHead);
198 }
199};
200static std::atomic<FileToRemoveList *> FilesToRemove = nullptr;
201
202/// Clean up the list in a signal-friendly manner.
203/// Recall that signals can fire during llvm_shutdown. If this occurs we should
204/// either clean something up or nothing at all, but we shouldn't crash!
205struct FilesToRemoveCleanup {
206 // Not signal-safe.
207 ~FilesToRemoveCleanup() {
208 FileToRemoveList *Head = FilesToRemove.exchange(nullptr);
209 if (Head)
210 delete Head;
211 }
212};
213} // namespace
214
215static StringRef Argv0;
216
217/// Signals that represent requested termination. There's no bug or failure, or
218/// if there is, it's not our direct responsibility. For whatever reason, our
219/// continued execution is no longer desirable.
220static const int IntSigs[] = {SIGHUP, SIGINT, SIGTERM, SIGUSR2};
221
222/// Signals that represent that we have a bug, and our prompt termination has
223/// been ordered.
224static const int KillSigs[] = {SIGILL,
225 SIGTRAP,
226 SIGABRT,
227 SIGFPE,
228 SIGBUS,
229 SIGSEGV,
230 SIGQUIT
231#ifdef SIGSYS
232 ,
233 SIGSYS
234#endif
235#ifdef SIGXCPU
236 ,
237 SIGXCPU
238#endif
239#ifdef SIGXFSZ
240 ,
241 SIGXFSZ
242#endif
243#ifdef SIGEMT
244 ,
245 SIGEMT
246#endif
247};
248
249/// Signals that represent requests for status.
250static const int InfoSigs[] = {SIGUSR1
251#ifdef SIGINFO
252 ,
253 SIGINFO
254#endif
255};
256
257static const size_t NumSigs = std::size(IntSigs) + std::size(KillSigs) +
258 std::size(InfoSigs) + 1 /* SIGPIPE */;
259
260static std::atomic<unsigned> NumRegisteredSignals = 0;
261static struct {
262 struct sigaction SA;
263 int SigNo;
264} RegisteredSignalInfo[NumSigs];
265
266#if defined(HAVE_SIGALTSTACK)
267// Hold onto both the old and new alternate signal stack so that it's not
268// reported as a leak. We don't make any attempt to remove our alt signal
269// stack if we remove our signal handlers; that can't be done reliably if
270// someone else is also trying to do the same thing.
271static stack_t OldAltStack;
272LLVM_ATTRIBUTE_USED static void *NewAltStackPointer;
273
274static void CreateSigAltStack() {
275 const size_t AltStackSize = MINSIGSTKSZ + 64 * 1024;
276
277 // If we're executing on the alternate stack, or we already have an alternate
278 // signal stack that we're happy with, there's nothing for us to do. Don't
279 // reduce the size, some other part of the process might need a larger stack
280 // than we do.
281 if (sigaltstack(nullptr, &OldAltStack) != 0 ||
282 OldAltStack.ss_flags & SS_ONSTACK ||
283 (OldAltStack.ss_sp && OldAltStack.ss_size >= AltStackSize))
284 return;
285
286 stack_t AltStack = {};
287 AltStack.ss_sp = static_cast<char *>(safe_malloc(AltStackSize));
288 NewAltStackPointer = AltStack.ss_sp; // Save to avoid reporting a leak.
289 AltStack.ss_size = AltStackSize;
290 if (sigaltstack(&AltStack, &OldAltStack) != 0)
291 free(AltStack.ss_sp);
292}
293#else
294static void CreateSigAltStack() {}
295#endif
296
297static void RegisterHandlers(
298 bool NeedsPOSIXUtilitySignalHandling = false) { // Not signal-safe.
299 // The mutex prevents other threads from registering handlers while we're
300 // doing it. We also have to protect the handlers and their count because
301 // a signal handler could fire while we're registering handlers.
302 static ManagedStatic<sys::SmartMutex<true>> SignalHandlerRegistrationMutex;
303 sys::SmartScopedLock<true> Guard(*SignalHandlerRegistrationMutex);
304
305 // If the handlers are already registered, we're done.
306 if (NumRegisteredSignals.load() != 0)
307 return;
308
309 // Create an alternate stack for signal handling. This is necessary for us to
310 // be able to reliably handle signals due to stack overflow.
311 CreateSigAltStack();
312
313 enum class SignalKind { IsKill, IsInfo };
314 auto registerHandler = [&](int Signal, SignalKind Kind) {
315 unsigned Index = NumRegisteredSignals.load();
316 assert(Index < std::size(RegisteredSignalInfo) &&
317 "Out of space for signal handlers!");
318
319 struct sigaction NewHandler;
320
321 switch (Kind) {
322 case SignalKind::IsKill:
323 if (NeedsPOSIXUtilitySignalHandling)
324 // If POSIX signal-handling semantics are followed, the signal handler
325 // resignal itself to terminate after handling the signal.
326 NewHandler.sa_sigaction = SignalHandlerTerminate;
327 else
328 NewHandler.sa_sigaction = SignalHandler;
329 NewHandler.sa_flags = SA_NODEFER | SA_RESETHAND | SA_ONSTACK | SA_SIGINFO;
330 break;
331 case SignalKind::IsInfo:
332 if (NeedsPOSIXUtilitySignalHandling)
333 // If POSIX signal-handling semantics are followed, the signal handler
334 // resignal itself to terminate after handling the signal.
335 NewHandler.sa_handler = InfoSignalHandlerTerminate;
336 else
337 NewHandler.sa_handler = InfoSignalHandler;
338 NewHandler.sa_flags = SA_ONSTACK;
339 break;
340 }
341 sigemptyset(&NewHandler.sa_mask);
342
343 if (NeedsPOSIXUtilitySignalHandling) {
344 // Don't install the new handler if the signal disposition is SIG_IGN.
345 struct sigaction act;
346 if (sigaction(Signal, NULL, &act) == 0 && act.sa_handler != SIG_IGN)
347 sigaction(Signal, &NewHandler, &RegisteredSignalInfo[Index].SA);
348 } else {
349 sigaction(Signal, &NewHandler, &RegisteredSignalInfo[Index].SA);
350 }
351 RegisteredSignalInfo[Index].SigNo = Signal;
352 ++NumRegisteredSignals;
353 };
354
355 for (auto S : IntSigs)
356 registerHandler(S, SignalKind::IsKill);
357 for (auto S : KillSigs)
358 registerHandler(S, SignalKind::IsKill);
359 if (OneShotPipeSignalFunction)
360 registerHandler(SIGPIPE, SignalKind::IsKill);
361 for (auto S : InfoSigs)
362 registerHandler(S, SignalKind::IsInfo);
363}
364
366 // Restore all of the signal handlers to how they were before we showed up.
367 for (unsigned i = 0, e = NumRegisteredSignals.load(); i != e; ++i) {
368 sigaction(RegisteredSignalInfo[i].SigNo, &RegisteredSignalInfo[i].SA,
369 nullptr);
370 --NumRegisteredSignals;
371 }
372}
373
374/// Process the FilesToRemove list.
375static void RemoveFilesToRemove() {
376 FileToRemoveList::removeAllFiles(FilesToRemove);
377}
378
379void sys::CleanupOnSignal(uintptr_t Context) {
380 // Let's not interfere with stack trace symbolication and friends.
381 auto BypassSandbox = sandbox::scopedDisable();
382
383 int Sig = (int)Context;
384
385 if (llvm::is_contained(InfoSigs, Sig)) {
386 InfoSignalHandler(Sig);
387 return;
388 }
389
390 RemoveFilesToRemove();
391
392 if (llvm::is_contained(IntSigs, Sig) || Sig == SIGPIPE)
393 return;
394
396}
397
398// The signal handler that runs.
399static void SignalHandler(int Sig, siginfo_t *Info, void *Context) {
400 // Restore the signal behavior to default, so that the program actually
401 // crashes when we return and the signal reissues. This also ensures that if
402 // we crash in our signal handler that the program will terminate immediately
403 // instead of recursing in the signal handler.
405
406 // Unmask all potentially blocked kill signals.
407 sigset_t SigMask;
408 sigfillset(&SigMask);
409 sigprocmask(SIG_UNBLOCK, &SigMask, nullptr);
410
411 {
412 RemoveFilesToRemove();
413
414 if (Sig == SIGPIPE)
415 if (auto OldOneShotPipeFunction =
416 OneShotPipeSignalFunction.exchange(nullptr))
417 return OldOneShotPipeFunction();
418
419 bool IsIntSig = llvm::is_contained(IntSigs, Sig);
420 if (IsIntSig)
421 if (auto OldInterruptFunction = InterruptFunction.exchange(nullptr))
422 return OldInterruptFunction();
423
424 if (Sig == SIGPIPE || IsIntSig) {
425 raise(Sig); // Execute the default handler.
426 return;
427 }
428 }
429
430 // Otherwise if it is a fault (like SEGV) run any handler.
432
433#ifdef __s390__
434 // On S/390, certain signals are delivered with PSW Address pointing to
435 // *after* the faulting instruction. Simply returning from the signal
436 // handler would continue execution after that point, instead of
437 // re-raising the signal. Raise the signal manually in those cases.
438 if (Sig == SIGILL || Sig == SIGFPE || Sig == SIGTRAP)
439 raise(Sig);
440#endif
441
442#if defined(__linux__)
443 // Re-raising a signal via `raise` loses the original siginfo. Recent
444 // versions of linux (>= 3.9) support processes sending a signal to itself
445 // with arbitrary signal information using a syscall. If this syscall is
446 // unsupported, errno will be set to EPERM and `raise` will be used instead.
447 int retval =
448 syscall(SYS_rt_tgsigqueueinfo, getpid(), syscall(SYS_gettid), Sig, Info);
449 if (retval != 0 && errno == EPERM)
450 raise(Sig);
451#else
452 // Signal sent from another userspace process, do not assume that continuing
453 // the execution would re-raise it.
454 if (Info->si_pid != getpid() && Info->si_pid != 0)
455 raise(Sig);
456#endif
457}
458
459static void SignalHandlerTerminate(int Sig, siginfo_t *Info, void *Context) {
460 SignalHandler(Sig, Info, Context);
461
462 // Resignal if it is a kill signal so that the exit code contains the
463 // terminating signal number.
464 if (llvm::is_contained(KillSigs, Sig))
465 raise(Sig); // Execute the default handler.
466}
467
468static void InfoSignalHandler(int Sig) {
469 SaveAndRestore SaveErrnoDuringASignalHandler(errno);
470 if (SignalHandlerFunctionType CurrentInfoFunction = InfoSignalFunction)
471 CurrentInfoFunction();
472}
473
474static void InfoSignalHandlerTerminate(int Sig) {
475 InfoSignalHandler(Sig);
476
477 if (Sig == SIGUSR1) {
479 raise(Sig);
480 }
481}
482
484 // Let's not interfere with stack trace symbolication and friends.
485 auto BypassSandbox = sandbox::scopedDisable();
486
487 RemoveFilesToRemove();
488}
489
490void llvm::sys::SetInterruptFunction(void (*IF)()) {
491 InterruptFunction.exchange(IF);
492 RegisterHandlers();
493}
494
495void llvm::sys::SetInfoSignalFunction(void (*Handler)()) {
496 InfoSignalFunction.exchange(Handler);
497 RegisterHandlers();
498}
499
500void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) {
501 OneShotPipeSignalFunction.exchange(Handler);
502 RegisterHandlers();
503}
504
506 // Send a special return code that drivers can check for, from sysexits.h.
507 exit(EX_IOERR);
508}
509
510// The public API
511bool llvm::sys::RemoveFileOnSignal(StringRef Filename, std::string *ErrMsg) {
512 // Ensure that cleanup will occur as soon as one file is added.
513 static ManagedStatic<FilesToRemoveCleanup> FilesToRemoveCleanup;
514 *FilesToRemoveCleanup;
515 FileToRemoveList::insert(FilesToRemove, Filename.str());
516 RegisterHandlers();
517 return false;
518}
519
520// The public API
522 FileToRemoveList::erase(FilesToRemove, Filename.str());
523}
524
525/// Add a function to be called when a signal is delivered to the process. The
526/// handler can have a cookie passed to it to identify what instance of the
527/// handler it is.
529 bool NeedsPOSIXUtilitySignalHandling) {
530 // Signal-safe.
531 insertSignalHandler(FnPtr, Cookie);
532 RegisterHandlers(NeedsPOSIXUtilitySignalHandling);
533}
534
535#if ENABLE_BACKTRACES && defined(HAVE_BACKTRACE) && \
536 (defined(__linux__) || defined(__FreeBSD__) || \
537 defined(__FreeBSD_kernel__) || defined(__NetBSD__) || \
538 defined(__OpenBSD__) || defined(__DragonFly__))
539struct DlIteratePhdrData {
540 void **StackTrace;
541 int depth;
542 bool first;
543 const char **modules;
544 intptr_t *offsets;
545 const char *main_exec_name;
546};
547
548static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
549 DlIteratePhdrData *data = (DlIteratePhdrData *)arg;
550 const char *name = data->first ? data->main_exec_name : info->dlpi_name;
551 data->first = false;
552 for (int i = 0; i < info->dlpi_phnum; i++) {
553 const auto *phdr = &info->dlpi_phdr[i];
554 if (phdr->p_type != PT_LOAD)
555 continue;
556 intptr_t beg = info->dlpi_addr + phdr->p_vaddr;
557 intptr_t end = beg + phdr->p_memsz;
558 for (int j = 0; j < data->depth; j++) {
559 if (data->modules[j])
560 continue;
561 intptr_t addr = (intptr_t)data->StackTrace[j];
562 if (beg <= addr && addr < end) {
563 data->modules[j] = name;
564 data->offsets[j] = addr - info->dlpi_addr;
565 }
566 }
567 }
568 return 0;
569}
570
571#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
572#if !defined(HAVE_BACKTRACE)
573#error DebugLoc origin-tracking currently requires `backtrace()`.
574#endif
575namespace llvm {
576namespace sys {
577template <unsigned long MaxDepth>
578int getStackTrace(std::array<void *, MaxDepth> &StackTrace) {
579 return backtrace(StackTrace.data(), MaxDepth);
580}
581template int getStackTrace<16ul>(std::array<void *, 16ul> &);
582} // namespace sys
583} // namespace llvm
584#endif
585
586/// If this is an ELF platform, we can find all loaded modules and their virtual
587/// addresses with dl_iterate_phdr.
588static bool findModulesAndOffsets(void **StackTrace, int Depth,
589 const char **Modules, intptr_t *Offsets,
590 const char *MainExecutableName,
591 StringSaver &StrPool) {
592 DlIteratePhdrData data = {StackTrace, Depth, true,
593 Modules, Offsets, MainExecutableName};
594 dl_iterate_phdr(dl_iterate_phdr_cb, &data);
595 return true;
596}
597
598class DSOMarkupPrinter {
600 const char *MainExecutableName;
601 size_t ModuleCount = 0;
602 bool IsFirst = true;
603
604public:
605 DSOMarkupPrinter(llvm::raw_ostream &OS, const char *MainExecutableName)
606 : OS(OS), MainExecutableName(MainExecutableName) {}
607
608 /// Print llvm-symbolizer markup describing the layout of the given DSO.
609 void printDSOMarkup(dl_phdr_info *Info) {
610 ArrayRef<uint8_t> BuildID = findBuildID(Info);
611 if (BuildID.empty())
612 return;
613 OS << format("{{{module:%d:%s:elf:", ModuleCount,
614 IsFirst ? MainExecutableName : Info->dlpi_name);
615 for (uint8_t X : BuildID)
616 OS << format("%02x", X);
617 OS << "}}}\n";
618
619 for (int I = 0; I < Info->dlpi_phnum; I++) {
620 const auto *Phdr = &Info->dlpi_phdr[I];
621 if (Phdr->p_type != PT_LOAD)
622 continue;
623 uintptr_t StartAddress = Info->dlpi_addr + Phdr->p_vaddr;
624 uintptr_t ModuleRelativeAddress = Phdr->p_vaddr;
625 std::array<char, 4> ModeStr = modeStrFromFlags(Phdr->p_flags);
626 OS << format("{{{mmap:%#016x:%#x:load:%d:%s:%#016x}}}\n", StartAddress,
627 Phdr->p_memsz, ModuleCount, &ModeStr[0],
628 ModuleRelativeAddress);
629 }
630 IsFirst = false;
631 ModuleCount++;
632 }
633
634 /// Callback for use with dl_iterate_phdr. The last dl_iterate_phdr argument
635 /// must be a pointer to an instance of this class.
636 static int printDSOMarkup(dl_phdr_info *Info, size_t Size, void *Arg) {
637 static_cast<DSOMarkupPrinter *>(Arg)->printDSOMarkup(Info);
638 return 0;
639 }
640
641 // Returns the build ID for the given DSO as an array of bytes. Returns an
642 // empty array if none could be found.
643 ArrayRef<uint8_t> findBuildID(dl_phdr_info *Info) {
644 for (int I = 0; I < Info->dlpi_phnum; I++) {
645 const auto *Phdr = &Info->dlpi_phdr[I];
646 if (Phdr->p_type != PT_NOTE)
647 continue;
648
649 ArrayRef<uint8_t> Notes(
650 reinterpret_cast<const uint8_t *>(Info->dlpi_addr + Phdr->p_vaddr),
651 Phdr->p_memsz);
652 while (Notes.size() > 12) {
653 uint32_t NameSize = *reinterpret_cast<const uint32_t *>(Notes.data());
654 Notes = Notes.drop_front(4);
655 uint32_t DescSize = *reinterpret_cast<const uint32_t *>(Notes.data());
656 Notes = Notes.drop_front(4);
657 uint32_t Type = *reinterpret_cast<const uint32_t *>(Notes.data());
658 Notes = Notes.drop_front(4);
659
660 ArrayRef<uint8_t> Name = Notes.take_front(NameSize);
661 auto CurPos = reinterpret_cast<uintptr_t>(Notes.data());
662 uint32_t BytesUntilDesc =
663 alignToPowerOf2(CurPos + NameSize, 4) - CurPos;
664 if (BytesUntilDesc >= Notes.size())
665 break;
666 Notes = Notes.drop_front(BytesUntilDesc);
667
668 ArrayRef<uint8_t> Desc = Notes.take_front(DescSize);
669 CurPos = reinterpret_cast<uintptr_t>(Notes.data());
670 uint32_t BytesUntilNextNote =
671 alignToPowerOf2(CurPos + DescSize, 4) - CurPos;
672 if (BytesUntilNextNote > Notes.size())
673 break;
674 Notes = Notes.drop_front(BytesUntilNextNote);
675
676 if (Type == 3 /*NT_GNU_BUILD_ID*/ && Name.size() >= 3 &&
677 Name[0] == 'G' && Name[1] == 'N' && Name[2] == 'U')
678 return Desc;
679 }
680 }
681 return {};
682 }
683
684 // Returns a symbolizer markup string describing the permissions on a DSO
685 // with the given p_flags.
686 std::array<char, 4> modeStrFromFlags(uint32_t Flags) {
687 std::array<char, 4> Mode;
688 char *Cur = &Mode[0];
689 if (Flags & PF_R)
690 *Cur++ = 'r';
691 if (Flags & PF_W)
692 *Cur++ = 'w';
693 if (Flags & PF_X)
694 *Cur++ = 'x';
695 *Cur = '\0';
696 return Mode;
697 }
698};
699
701 const char *MainExecutableName) {
702 OS << "{{{reset}}}\n";
703 DSOMarkupPrinter MP(OS, MainExecutableName);
704 dl_iterate_phdr(DSOMarkupPrinter::printDSOMarkup, &MP);
705 return true;
706}
707
708#elif ENABLE_BACKTRACES && defined(__APPLE__) && defined(__LP64__)
709static bool findModulesAndOffsets(void **StackTrace, int Depth,
710 const char **Modules, intptr_t *Offsets,
711 const char *MainExecutableName,
712 StringSaver &StrPool) {
713 uint32_t NumImgs = _dyld_image_count();
714 for (uint32_t ImageIndex = 0; ImageIndex < NumImgs; ImageIndex++) {
715 const char *Name = _dyld_get_image_name(ImageIndex);
716 intptr_t Slide = _dyld_get_image_vmaddr_slide(ImageIndex);
717 auto *Header =
718 (const struct mach_header_64 *)_dyld_get_image_header(ImageIndex);
719 if (Header == NULL)
720 continue;
721 auto Cmd = (const struct load_command *)(&Header[1]);
722 for (uint32_t CmdNum = 0; CmdNum < Header->ncmds; ++CmdNum) {
723 uint32_t BaseCmd = Cmd->cmd & ~LC_REQ_DYLD;
724 if (BaseCmd == LC_SEGMENT_64) {
725 auto CmdSeg64 = (const struct segment_command_64 *)Cmd;
726 for (int j = 0; j < Depth; j++) {
727 if (Modules[j])
728 continue;
729 intptr_t Addr = (intptr_t)StackTrace[j];
730 if ((intptr_t)CmdSeg64->vmaddr + Slide <= Addr &&
731 Addr < intptr_t(CmdSeg64->vmaddr + CmdSeg64->vmsize + Slide)) {
732 Modules[j] = Name;
733 Offsets[j] = Addr - Slide;
734 }
735 }
736 }
737 Cmd = (const load_command *)(((const char *)Cmd) + (Cmd->cmdsize));
738 }
739 }
740 return true;
741}
742
744 const char *MainExecutableName) {
745 return false;
746}
747#else
748/// Backtraces are not enabled or we don't yet know how to find all loaded DSOs
749/// on this platform.
750static bool findModulesAndOffsets(void **StackTrace, int Depth,
751 const char **Modules, intptr_t *Offsets,
752 const char *MainExecutableName,
753 StringSaver &StrPool) {
754 return false;
755}
756
758 const char *MainExecutableName) {
759 return false;
760}
761#endif // ENABLE_BACKTRACES && ... (findModulesAndOffsets variants)
762
763#if ENABLE_BACKTRACES && defined(HAVE__UNWIND_BACKTRACE)
764static int unwindBacktrace(void **StackTrace, int MaxEntries) {
765 if (MaxEntries < 0)
766 return 0;
767
768 // Skip the first frame ('unwindBacktrace' itself).
769 int Entries = -1;
770
771 auto HandleFrame = [&](_Unwind_Context *Context) -> _Unwind_Reason_Code {
772 // Apparently we need to detect reaching the end of the stack ourselves.
773 void *IP = (void *)_Unwind_GetIP(Context);
774 if (!IP)
775 return _URC_END_OF_STACK;
776
777 assert(Entries < MaxEntries && "recursively called after END_OF_STACK?");
778 if (Entries >= 0)
779 StackTrace[Entries] = IP;
780
781 if (++Entries == MaxEntries)
782 return _URC_END_OF_STACK;
783 return _URC_NO_REASON;
784 };
785
786 _Unwind_Backtrace(
787 [](_Unwind_Context *Context, void *Handler) {
788 return (*static_cast<decltype(HandleFrame) *>(Handler))(Context);
789 },
790 static_cast<void *>(&HandleFrame));
791 return std::max(Entries, 0);
792}
793#endif
794
795#if ENABLE_BACKTRACES && defined(__MVS__)
796static void zosbacktrace(raw_ostream &OS) {
797 // A function name in the PPA1 can have length 16k.
798 constexpr size_t MAX_ENTRY_NAME = UINT16_MAX;
799 // Limit all other strings to 8 byte.
800 constexpr size_t MAX_OTHER = 8;
801 int32_t dsa_format = -1; // Input/Output
802 void *caaptr = _gtca(); // Input
803 int32_t member_id; // Output
804 char compile_unit_name[MAX_OTHER]; // Output
805 void *compile_unit_address; // Output
806 void *call_instruction_address = nullptr; // Input/Output
807 char entry_name[MAX_ENTRY_NAME]; // Output
808 void *entry_address; // Output
809 void *callers_instruction_address; // Output
810 void *callers_dsaptr; // Output
811 int32_t callers_dsa_format; // Output
812 char statement_id[MAX_OTHER]; // Output
813 void *cibptr; // Output
814 int32_t main_program; // Output
815 _FEEDBACK fc; // Output
816
817 // The DSA pointer is the value of the stack pointer r4.
818 // __builtin_frame_address() returns a pointer to the stack frame, so the
819 // stack bias has to be considered to get the expected DSA value.
820 void *dsaptr = static_cast<char *>(__builtin_frame_address(0)) - 2048;
821 int count = 0;
822 OS << " DSA Adr EP +EP DSA "
823 " Entry\n";
824 while (1) {
825 // After the call, these variables contain the length of the string.
826 int32_t compile_unit_name_length = sizeof(compile_unit_name);
827 int32_t entry_name_length = sizeof(entry_name);
828 int32_t statement_id_length = sizeof(statement_id);
829 // See
830 // https://www.ibm.com/docs/en/zos/3.1.0?topic=cwicsa6a-celqtbck-also-known-as-celqtbck-64-bit-traceback-service
831 // for documentation of the parameters.
832 __CELQTBCK(&dsaptr, &dsa_format, &caaptr, &member_id, &compile_unit_name[0],
833 &compile_unit_name_length, &compile_unit_address,
834 &call_instruction_address, &entry_name[0], &entry_name_length,
835 &entry_address, &callers_instruction_address, &callers_dsaptr,
836 &callers_dsa_format, &statement_id[0], &statement_id_length,
837 &cibptr, &main_program, &fc);
838 if (fc.tok_sev) {
839 OS << format("error: CELQTBCK returned severity %d message %d\n",
840 fc.tok_sev, fc.tok_msgno);
841 break;
842 }
843
844 if (count) { // Omit first entry.
845 uintptr_t diff = reinterpret_cast<uintptr_t>(call_instruction_address) -
846 reinterpret_cast<uintptr_t>(entry_address);
847 OS << format(" %3d. 0x%016lX", count, call_instruction_address);
848 OS << format(" 0x%016lX +0x%08lX 0x%016lX", entry_address, diff, dsaptr);
850 ConverterEBCDIC::convertToUTF8(StringRef(entry_name, entry_name_length),
851 Str);
852 OS << ' ' << Str << '\n';
853 }
854 ++count;
855 if (callers_dsaptr) {
856 dsaptr = callers_dsaptr;
857 dsa_format = callers_dsa_format;
858 call_instruction_address = callers_instruction_address;
859 } else
860 break;
861 }
862}
863#endif
864
865// In the case of a program crash or fault, print out a stack trace so that the
866// user has an indication of why and where we died.
867//
868// On glibc systems we have the 'backtrace' function, which works nicely, but
869// doesn't demangle symbols.
871#if ENABLE_BACKTRACES
872#ifdef __MVS__
873 zosbacktrace(OS);
874#else
875 static void *StackTrace[256];
876 int depth = 0;
877#if defined(HAVE_BACKTRACE)
878 // Use backtrace() to output a backtrace on Linux systems with glibc.
879 if (!depth)
880 depth = backtrace(StackTrace, static_cast<int>(std::size(StackTrace)));
881#endif
882#if defined(HAVE__UNWIND_BACKTRACE)
883 // Try _Unwind_Backtrace() if backtrace() failed.
884 if (!depth)
885 depth =
886 unwindBacktrace(StackTrace, static_cast<int>(std::size(StackTrace)));
887#endif
888 if (!depth)
889 return;
890 // If "Depth" is not provided by the caller, use the return value of
891 // backtrace() for printing a symbolized stack trace.
892 if (!Depth)
893 Depth = depth;
894 if (printMarkupStackTrace(Argv0, StackTrace, Depth, OS))
895 return;
896 if (printSymbolizedStackTrace(Argv0, StackTrace, Depth, OS))
897 return;
898 OS << "Stack dump without symbol names (ensure you have llvm-symbolizer in "
899 "your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point "
900 "to it):\n";
901#if HAVE_DLOPEN && !defined(_AIX)
902 int width = 0;
903 for (int i = 0; i < depth; ++i) {
904 Dl_info dlinfo;
905 int nwidth;
906 if (dladdr(StackTrace[i], &dlinfo) == 0) {
907 nwidth = 7; // "(error)"
908 } else {
909 const char *name = strrchr(dlinfo.dli_fname, '/');
910
911 if (!name)
912 nwidth = strlen(dlinfo.dli_fname);
913 else
914 nwidth = strlen(name) - 1;
915 }
916
917 width = std::max(nwidth, width);
918 }
919
920 for (int i = 0; i < depth; ++i) {
921 Dl_info dlinfo;
922
923 OS << format("%-2d", i);
924
925 if (dladdr(StackTrace[i], &dlinfo) == 0) {
926 OS << format(" %-*s", width, static_cast<const char *>("(error)"));
927 dlinfo.dli_sname = nullptr;
928 } else {
929 const char *name = strrchr(dlinfo.dli_fname, '/');
930 if (!name)
931 OS << format(" %-*s", width, dlinfo.dli_fname);
932 else
933 OS << format(" %-*s", width, name + 1);
934 }
935
936 OS << format(" %#0*lx", (int)(sizeof(void *) * 2) + 2,
937 (unsigned long)StackTrace[i]);
938
939 if (dlinfo.dli_sname != nullptr) {
940 OS << ' ';
941 if (char *d = itaniumDemangle(dlinfo.dli_sname)) {
942 OS << d;
943 free(d);
944 } else {
945 OS << dlinfo.dli_sname;
946 }
947
948 OS << format(" + %tu", (static_cast<const char *>(StackTrace[i]) -
949 static_cast<const char *>(dlinfo.dli_saddr)));
950 }
951 OS << '\n';
952 }
953#elif defined(HAVE_BACKTRACE)
954 backtrace_symbols_fd(StackTrace, Depth, STDERR_FILENO);
955#endif
956#endif
957#endif
958}
959
960static void PrintStackTraceSignalHandler(void *) {
962}
963
965
966/// When an error signal (such as SIGABRT or SIGSEGV) is delivered to the
967/// process, print a stack trace and then exit.
969 bool DisableCrashReporting) {
970 ::Argv0 = Argv0;
971
972 AddSignalHandler(PrintStackTraceSignalHandler, nullptr);
973
974#if defined(__APPLE__) && ENABLE_CRASH_OVERRIDES
975 // Environment variable to disable any kind of crash dialog.
976 if (DisableCrashReporting || getenv("LLVM_DISABLE_CRASH_REPORT")) {
977 mach_port_t self = mach_task_self();
978
979 exception_mask_t mask = EXC_MASK_CRASH;
980
981 kern_return_t ret = task_set_exception_ports(
982 self, mask, MACH_PORT_NULL,
983 EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
984 (void)ret;
985 }
986#endif
987}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static constexpr unsigned long long mask(BlockVerifier::State S)
#define LLVM_ATTRIBUTE_USED
Definition Compiler.h:236
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")))
static const char * name
This file contains some templates that are useful if you are working with the STL at all.
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:339
static void insertSignalHandler(sys::SignalHandlerCallback FnPtr, void *Cookie)
Definition Signals.cpp:115
static Split data
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
ArrayRef - 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
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
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:26
iterator end() const
Definition BasicBlock.h:89
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.
Definition Types.h:26
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
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
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:493
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:129
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FunctionAddr VTableAddr Next
Definition InstrProf.h:141
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
#define N
A utility class that uses RAII to save and restore the value of a variable.