#include "Unix.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/config.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/Support/ExitCodes.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <string>
#ifdef HAVE_BACKTRACE
#include BACKTRACE_HEADER
#endif
#if HAVE_SIGNAL_H
#include <signal.h>
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_DLFCN_H
#include <dlfcn.h>
#endif
#if HAVE_MACH_MACH_H
#include <mach/mach.h>
#endif
#ifdef __APPLE__
#include <mach-o/dyld.h>
#endif
#if __has_include(<link.h>)
#include <link.h>
#endif
#ifdef HAVE__UNWIND_BACKTRACE
#ifdef __GLIBC__
#include <unwind.h>
#else
#undef HAVE__UNWIND_BACKTRACE
#endif
#endif
usingnamespacellvm;
static void SignalHandler(int Sig);
static void InfoSignalHandler(int Sig);
SignalHandlerFunctionType;
static std::atomic<SignalHandlerFunctionType> InterruptFunction = …;
static std::atomic<SignalHandlerFunctionType> InfoSignalFunction = …;
static std::atomic<SignalHandlerFunctionType> OneShotPipeSignalFunction = …;
namespace {
class FileToRemoveList { … };
static std::atomic<FileToRemoveList *> FilesToRemove = …;
struct FilesToRemoveCleanup { … };
}
static StringRef Argv0;
static const int IntSigs[] = …;
static const int KillSigs[] = …;
static const int InfoSigs[] = …;
static const size_t NumSigs = … ;
static std::atomic<unsigned> NumRegisteredSignals = …;
static struct { … } RegisteredSignalInfo[NumSigs];
#if defined(HAVE_SIGALTSTACK)
static stack_t OldAltStack;
LLVM_ATTRIBUTE_USED static void *NewAltStackPointer;
static void CreateSigAltStack() { … }
#else
static void CreateSigAltStack() {}
#endif
static void RegisterHandlers() { … }
void sys::unregisterHandlers() { … }
static void RemoveFilesToRemove() { … }
void sys::CleanupOnSignal(uintptr_t Context) { … }
static void SignalHandler(int Sig) { … }
static void InfoSignalHandler(int Sig) { … }
void llvm::sys::RunInterruptHandlers() { … }
void llvm::sys::SetInterruptFunction(void (*IF)()) { … }
void llvm::sys::SetInfoSignalFunction(void (*Handler)()) { … }
void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) { … }
void llvm::sys::DefaultOneShotPipeSignalHandler() { … }
bool llvm::sys::RemoveFileOnSignal(StringRef Filename, std::string *ErrMsg) { … }
void llvm::sys::DontRemoveFileOnSignal(StringRef Filename) { … }
void llvm::sys::AddSignalHandler(sys::SignalHandlerCallback FnPtr,
void *Cookie) { … }
#if ENABLE_BACKTRACES && defined(HAVE_BACKTRACE) && \
(defined(__linux__) || defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || defined(__NetBSD__))
struct DlIteratePhdrData { … };
static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) { … }
static bool findModulesAndOffsets(void **StackTrace, int Depth,
const char **Modules, intptr_t *Offsets,
const char *MainExecutableName,
StringSaver &StrPool) { … }
class DSOMarkupPrinter { … };
static bool printMarkupContext(llvm::raw_ostream &OS,
const char *MainExecutableName) { … }
#elif ENABLE_BACKTRACES && defined(__APPLE__) && defined(__LP64__)
static bool findModulesAndOffsets(void **StackTrace, int Depth,
const char **Modules, intptr_t *Offsets,
const char *MainExecutableName,
StringSaver &StrPool) {
uint32_t NumImgs = _dyld_image_count();
for (uint32_t ImageIndex = 0; ImageIndex < NumImgs; ImageIndex++) {
const char *Name = _dyld_get_image_name(ImageIndex);
intptr_t Slide = _dyld_get_image_vmaddr_slide(ImageIndex);
auto *Header =
(const struct mach_header_64 *)_dyld_get_image_header(ImageIndex);
if (Header == NULL)
continue;
auto Cmd = (const struct load_command *)(&Header[1]);
for (uint32_t CmdNum = 0; CmdNum < Header->ncmds; ++CmdNum) {
uint32_t BaseCmd = Cmd->cmd & ~LC_REQ_DYLD;
if (BaseCmd == LC_SEGMENT_64) {
auto CmdSeg64 = (const struct segment_command_64 *)Cmd;
for (int j = 0; j < Depth; j++) {
if (Modules[j])
continue;
intptr_t Addr = (intptr_t)StackTrace[j];
if ((intptr_t)CmdSeg64->vmaddr + Slide <= Addr &&
Addr < intptr_t(CmdSeg64->vmaddr + CmdSeg64->vmsize + Slide)) {
Modules[j] = Name;
Offsets[j] = Addr - Slide;
}
}
}
Cmd = (const load_command *)(((const char *)Cmd) + (Cmd->cmdsize));
}
}
return true;
}
static bool printMarkupContext(llvm::raw_ostream &OS,
const char *MainExecutableName) {
return false;
}
#else
static bool findModulesAndOffsets(void **StackTrace, int Depth,
const char **Modules, intptr_t *Offsets,
const char *MainExecutableName,
StringSaver &StrPool) {
return false;
}
static bool printMarkupContext(llvm::raw_ostream &OS,
const char *MainExecutableName) {
return false;
}
#endif
#if ENABLE_BACKTRACES && defined(HAVE__UNWIND_BACKTRACE)
static int unwindBacktrace(void **StackTrace, int MaxEntries) { … }
#endif
void llvm::sys::PrintStackTrace(raw_ostream &OS, int Depth) { … }
static void PrintStackTraceSignalHandler(void *) { … }
void llvm::sys::DisableSystemDialogsOnCrash() { … }
void llvm::sys::PrintStackTraceOnErrorSignal(StringRef Argv0,
bool DisableCrashReporting) { … }