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