1//===- Signals.cpp - Generic Unix Signals Implementation -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines some helpful functions for dealing with the possibility of
10// Unix signals occurring while your program is running.
11//
12//===----------------------------------------------------------------------===//
13//
14// This file is extremely careful to only do signal-safe things while in a
15// signal handler. In particular, memory allocation and acquiring a mutex
16// while in a signal handler should never occur. ManagedStatic isn't usable from
17// a signal handler for 2 reasons:
18//
19// 1. Creating a new one allocates.
20// 2. The signal handler could fire while llvm_shutdown is being processed, in
21// which case the ManagedStatic is in an unknown state because it could
22// already have been destroyed, or be in the process of being destroyed.
23//
24// Modifying the behavior of the signal handlers (such as registering new ones)
25// can acquire a mutex, but all this guarantees is that the signal handler
26// behavior is only modified by one thread at a time. A signal handler can still
27// fire while this occurs!
28//
29// Adding work to a signal handler requires lock-freedom (and assume atomics are
30// always lock-free) because the signal handler could fire while new work is
31// being added.
32//
33//===----------------------------------------------------------------------===//
34
35#include "Unix.h"
36#include "llvm/ADT/STLExtras.h"
37#include "llvm/Config/config.h"
38#include "llvm/Demangle/Demangle.h"
39#include "llvm/Support/ExitCodes.h"
40#include "llvm/Support/FileSystem.h"
41#include "llvm/Support/FileUtilities.h"
42#include "llvm/Support/Format.h"
43#include "llvm/Support/MemoryBuffer.h"
44#include "llvm/Support/Mutex.h"
45#include "llvm/Support/Program.h"
46#include "llvm/Support/SaveAndRestore.h"
47#include "llvm/Support/raw_ostream.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__)
77#include "llvm/Support/ConvertEBCDIC.h"
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(s: str.c_str())) {}
112
113public:
114 // Not signal-safe.
115 ~FileToRemoveList() {
116 if (FileToRemoveList *N = Next.exchange(p: nullptr))
117 delete N;
118 if (char *F = Filename.exchange(p: nullptr))
119 free(ptr: 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(p1&: OldHead, p2: 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(p: nullptr);
150 // The filename might have become null between the time we
151 // compared it and we exchanged it.
152 if (OldFilename)
153 free(ptr: 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(file: path, buf: &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(name: 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(p: 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(p: nullptr)) {
189 removeFile(path);
190
191 // We're done removing the file, erasing can safely proceed.
192 currentFile->Filename.exchange(p: path);
193 }
194 }
195
196 // We're done removing files, cleanup can safely proceed.
197 Head.exchange(p: 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(p: 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(ss: nullptr, oss: &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(Sz: AltStackSize));
288 NewAltStackPointer = AltStack.ss_sp; // Save to avoid reporting a leak.
289 AltStack.ss_size = AltStackSize;
290 if (sigaltstack(ss: &AltStack, oss: &OldAltStack) != 0)
291 free(ptr: 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(set: &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(sig: Signal, NULL, oact: &act) == 0 && act.sa_handler != SIG_IGN)
347 sigaction(sig: Signal, act: &NewHandler, oact: &RegisteredSignalInfo[Index].SA);
348 } else {
349 sigaction(sig: Signal, act: &NewHandler, oact: &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
365void sys::unregisterHandlers() {
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(sig: RegisteredSignalInfo[i].SigNo, act: &RegisteredSignalInfo[i].SA,
369 oact: nullptr);
370 --NumRegisteredSignals;
371 }
372}
373
374/// Process the FilesToRemove list.
375static void RemoveFilesToRemove() {
376 FileToRemoveList::removeAllFiles(Head&: 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(Range: InfoSigs, Element: Sig)) {
386 InfoSignalHandler(Sig);
387 return;
388 }
389
390 RemoveFilesToRemove();
391
392 if (llvm::is_contained(Range: IntSigs, Element: Sig) || Sig == SIGPIPE)
393 return;
394
395 llvm::sys::RunSignalHandlers();
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.
404 sys::unregisterHandlers();
405
406 // Unmask all potentially blocked kill signals.
407 sigset_t SigMask;
408 sigfillset(set: &SigMask);
409 sigprocmask(SIG_UNBLOCK, set: &SigMask, oset: nullptr);
410
411 {
412 RemoveFilesToRemove();
413
414 if (Sig == SIGPIPE)
415 if (auto OldOneShotPipeFunction =
416 OneShotPipeSignalFunction.exchange(p: nullptr))
417 return OldOneShotPipeFunction();
418
419 bool IsIntSig = llvm::is_contained(Range: IntSigs, Element: Sig);
420 if (IsIntSig)
421 if (auto OldInterruptFunction = InterruptFunction.exchange(p: nullptr))
422 return OldInterruptFunction();
423
424 if (Sig == SIGPIPE || IsIntSig) {
425 raise(sig: Sig); // Execute the default handler.
426 return;
427 }
428 }
429
430 // Otherwise if it is a fault (like SEGV) run any handler.
431 llvm::sys::RunSignalHandlers();
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: 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(Range: KillSigs, Element: Sig))
465 raise(sig: 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) {
478 sys::unregisterHandlers();
479 raise(sig: Sig);
480 }
481}
482
483void sys::RunInterruptHandlers() {
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(p: IF);
492 RegisterHandlers();
493}
494
495void llvm::sys::SetInfoSignalFunction(void (*Handler)()) {
496 InfoSignalFunction.exchange(p: Handler);
497 RegisterHandlers();
498}
499
500void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) {
501 OneShotPipeSignalFunction.exchange(p: Handler);
502 RegisterHandlers();
503}
504
505void llvm::sys::DefaultOneShotPipeSignalHandler() {
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(Head&: FilesToRemove, Filename: Filename.str());
516 RegisterHandlers();
517 return false;
518}
519
520// The public API
521void llvm::sys::DontRemoveFileOnSignal(StringRef Filename) {
522 FileToRemoveList::erase(Head&: FilesToRemove, Filename: 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.
528void llvm::sys::AddSignalHandler(sys::SignalHandlerCallback FnPtr, void *Cookie,
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: StackTrace, .depth: Depth, .first: true,
593 .modules: Modules, .offsets: Offsets, .main_exec_name: MainExecutableName};
594 dl_iterate_phdr(callback: dl_iterate_phdr_cb, data: &data);
595 return true;
596}
597
598class DSOMarkupPrinter {
599 llvm::raw_ostream &OS;
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(Fmt: "{{{module:%d:%s:elf:", Vals: ModuleCount,
614 Vals: IsFirst ? MainExecutableName : Info->dlpi_name);
615 for (uint8_t X : BuildID)
616 OS << format(Fmt: "%02x", Vals: 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(Flags: Phdr->p_flags);
626 OS << format(Fmt: "{{{mmap:%#016x:%#x:load:%d:%s:%#016x}}}\n", Vals: StartAddress,
627 Vals: Phdr->p_memsz, Vals: ModuleCount, Vals: &ModeStr[0],
628 Vals: 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(N: 4);
655 uint32_t DescSize = *reinterpret_cast<const uint32_t *>(Notes.data());
656 Notes = Notes.drop_front(N: 4);
657 uint32_t Type = *reinterpret_cast<const uint32_t *>(Notes.data());
658 Notes = Notes.drop_front(N: 4);
659
660 ArrayRef<uint8_t> Name = Notes.take_front(N: NameSize);
661 auto CurPos = reinterpret_cast<uintptr_t>(Notes.data());
662 uint32_t BytesUntilDesc =
663 alignToPowerOf2(Value: CurPos + NameSize, Align: 4) - CurPos;
664 if (BytesUntilDesc >= Notes.size())
665 break;
666 Notes = Notes.drop_front(N: BytesUntilDesc);
667
668 ArrayRef<uint8_t> Desc = Notes.take_front(N: DescSize);
669 CurPos = reinterpret_cast<uintptr_t>(Notes.data());
670 uint32_t BytesUntilNextNote =
671 alignToPowerOf2(Value: CurPos + DescSize, Align: 4) - CurPos;
672 if (BytesUntilNextNote > Notes.size())
673 break;
674 Notes = Notes.drop_front(N: 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
700static bool printMarkupContext(llvm::raw_ostream &OS,
701 const char *MainExecutableName) {
702 OS << "{{{reset}}}\n";
703 DSOMarkupPrinter MP(OS, MainExecutableName);
704 dl_iterate_phdr(callback: DSOMarkupPrinter::printDSOMarkup, data: &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
743static bool printMarkupContext(llvm::raw_ostream &OS,
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
757static bool printMarkupContext(llvm::raw_ostream &OS,
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(a: Entries, b: 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);
849 SmallString<256> Str;
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.
870void llvm::sys::PrintStackTrace(raw_ostream &OS, int Depth) {
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(array: StackTrace, size: 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, MaxEntries: 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(address: StackTrace[i], info: &dlinfo) == 0) {
907 nwidth = 7; // "(error)"
908 } else {
909 const char *name = strrchr(s: dlinfo.dli_fname, c: '/');
910
911 if (!name)
912 nwidth = strlen(s: dlinfo.dli_fname);
913 else
914 nwidth = strlen(s: name) - 1;
915 }
916
917 width = std::max(a: nwidth, b: width);
918 }
919
920 for (int i = 0; i < depth; ++i) {
921 Dl_info dlinfo;
922
923 OS << format(Fmt: "%-2d", Vals: i);
924
925 if (dladdr(address: StackTrace[i], info: &dlinfo) == 0) {
926 OS << format(Fmt: " %-*s", Vals: width, Vals: static_cast<const char *>("(error)"));
927 dlinfo.dli_sname = nullptr;
928 } else {
929 const char *name = strrchr(s: dlinfo.dli_fname, c: '/');
930 if (!name)
931 OS << format(Fmt: " %-*s", Vals: width, Vals: dlinfo.dli_fname);
932 else
933 OS << format(Fmt: " %-*s", Vals: width, Vals: name + 1);
934 }
935
936 OS << format(Fmt: " %#0*lx", Vals: (int)(sizeof(void *) * 2) + 2,
937 Vals: (unsigned long)StackTrace[i]);
938
939 if (dlinfo.dli_sname != nullptr) {
940 OS << ' ';
941 if (char *d = itaniumDemangle(mangled_name: dlinfo.dli_sname)) {
942 OS << d;
943 free(ptr: d);
944 } else {
945 OS << dlinfo.dli_sname;
946 }
947
948 OS << format(Fmt: " + %tu", Vals: (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 *) {
961 sys::PrintStackTrace(OS&: llvm::errs());
962}
963
964void llvm::sys::DisableSystemDialogsOnCrash() {}
965
966/// When an error signal (such as SIGABRT or SIGSEGV) is delivered to the
967/// process, print a stack trace and then exit.
968void llvm::sys::PrintStackTraceOnErrorSignal(StringRef Argv0,
969 bool DisableCrashReporting) {
970 ::Argv0 = Argv0;
971
972 AddSignalHandler(FnPtr: PrintStackTraceSignalHandler, Cookie: 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}
988