37#include "llvm/Config/config.h"
51#include BACKTRACE_HEADER
60#include <mach-o/dyld.h>
62#if __has_include(<link.h>)
65#ifdef HAVE__UNWIND_BACKTRACE
73#undef HAVE__UNWIND_BACKTRACE
76#if ENABLE_BACKTRACES && defined(__MVS__)
82#include <sys/syscall.h>
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);
90static void InfoSignalHandlerTerminate(
int Sig);
92using SignalHandlerFunctionType = void (*)();
94static std::atomic<SignalHandlerFunctionType> InterruptFunction =
nullptr;
95static std::atomic<SignalHandlerFunctionType> InfoSignalFunction =
nullptr;
97static std::atomic<SignalHandlerFunctionType> OneShotPipeSignalFunction =
103static char InvalidPathSentinel[] =
"\01\02\03\04";
109class FileToRemoveList {
110 std::atomic<char *>
Filename =
nullptr;
111 std::atomic<FileToRemoveList *>
Next =
nullptr;
113 FileToRemoveList() =
default;
119 ~FileToRemoveList() {
120 if (FileToRemoveList *
N =
Next.exchange(
nullptr))
122 if (
char *
F =
Filename.exchange(
nullptr))
123 if (
F != InvalidPathSentinel)
128 static void insert(std::atomic<FileToRemoveList *> &Head,
136 char *NewFilename = strdup(
Filename.c_str());
137 std::atomic<FileToRemoveList *> *InsertionPoint = &Head;
138 for (FileToRemoveList *Current = Head.load(); Current;
139 Current = Current->Next.load()) {
140 char *NullFilename =
nullptr;
141 if (Current->Filename.compare_exchange_strong(NullFilename, NewFilename))
143 InsertionPoint = &Current->Next;
147 FileToRemoveList *NewNode =
new FileToRemoveList(NewFilename);
148 FileToRemoveList *OldNext =
nullptr;
149 while (!InsertionPoint->compare_exchange_strong(OldNext, NewNode)) {
150 InsertionPoint = &OldNext->Next;
156 static void erase(std::atomic<FileToRemoveList *> &Head,
160 static ManagedStatic<sys::SmartMutex<true>> Lock;
161 sys::SmartScopedLock<true> Writer(*Lock);
163 for (FileToRemoveList *Current = Head.load(); Current;
164 Current = Current->Next.load()) {
165 if (
char *OldFilename = Current->Filename.load()) {
171 char *Expected = OldFilename;
172 while (!Current->Filename.compare_exchange_strong(Expected,
nullptr)) {
173 if (Expected ==
nullptr || Expected == InvalidPathSentinel)
176 if (Expected == OldFilename)
182 static void removeFile(
char *path) {
186 if (stat(path, &buf) != 0)
192 if (!S_ISREG(buf.st_mode))
201 static void removeAllFiles(std::atomic<FileToRemoveList *> &Head) {
204 FileToRemoveList *OldHead = Head.exchange(
nullptr);
206 for (FileToRemoveList *currentFile = OldHead; currentFile;
207 currentFile = currentFile->Next.load()) {
210 char *
Path = currentFile->Filename.exchange(InvalidPathSentinel);
213 currentFile->Filename.exchange(
nullptr);
214 }
else if (Path != InvalidPathSentinel) {
218 currentFile->Filename.exchange(Path);
223 Head.exchange(OldHead);
226static std::atomic<FileToRemoveList *> FilesToRemove =
nullptr;
231struct FilesToRemoveCleanup {
233 ~FilesToRemoveCleanup() {
234 FileToRemoveList *Head = FilesToRemove.exchange(
nullptr);
246static const int IntSigs[] = {SIGHUP, SIGINT, SIGTERM, SIGUSR2};
250static const int KillSigs[] = {SIGILL,
276static const int InfoSigs[] = {SIGUSR1
283static const size_t NumSigs = std::size(IntSigs) + std::size(KillSigs) +
284 std::size(InfoSigs) + 1 ;
286static std::atomic<unsigned> NumRegisteredSignals = 0;
290} RegisteredSignalInfo[NumSigs];
292#if defined(HAVE_SIGALTSTACK)
297static stack_t OldAltStack;
300static void CreateSigAltStack() {
301 const size_t AltStackSize = MINSIGSTKSZ + 64 * 1024;
307 if (sigaltstack(
nullptr, &OldAltStack) != 0 ||
308 OldAltStack.ss_flags & SS_ONSTACK ||
309 (OldAltStack.ss_sp && OldAltStack.ss_size >= AltStackSize))
312 stack_t AltStack = {};
313 AltStack.ss_sp =
static_cast<char *
>(
safe_malloc(AltStackSize));
314 NewAltStackPointer = AltStack.ss_sp;
315 AltStack.ss_size = AltStackSize;
316 if (sigaltstack(&AltStack, &OldAltStack) != 0)
317 free(AltStack.ss_sp);
320static void CreateSigAltStack() {}
323static void RegisterHandlers(
324 bool NeedsPOSIXUtilitySignalHandling =
false) {
332 if (NumRegisteredSignals.load() != 0)
339 enum class SignalKind { IsKill, IsInfo };
340 auto registerHandler = [&](
int Signal, SignalKind Kind) {
341 unsigned Index = NumRegisteredSignals.load();
342 assert(Index < std::size(RegisteredSignalInfo) &&
343 "Out of space for signal handlers!");
345 struct sigaction NewHandler;
348 case SignalKind::IsKill:
349 if (NeedsPOSIXUtilitySignalHandling)
352 NewHandler.sa_sigaction = SignalHandlerTerminate;
354 NewHandler.sa_sigaction = SignalHandler;
355 NewHandler.sa_flags = SA_NODEFER | SA_RESETHAND | SA_ONSTACK | SA_SIGINFO;
357 case SignalKind::IsInfo:
358 if (NeedsPOSIXUtilitySignalHandling)
361 NewHandler.sa_handler = InfoSignalHandlerTerminate;
363 NewHandler.sa_handler = InfoSignalHandler;
364 NewHandler.sa_flags = SA_ONSTACK;
367 sigemptyset(&NewHandler.sa_mask);
369 if (NeedsPOSIXUtilitySignalHandling) {
371 struct sigaction act;
372 if (sigaction(Signal, NULL, &act) == 0 && act.sa_handler != SIG_IGN)
373 sigaction(Signal, &NewHandler, &RegisteredSignalInfo[Index].SA);
375 sigaction(Signal, &NewHandler, &RegisteredSignalInfo[Index].SA);
377 RegisteredSignalInfo[Index].SigNo = Signal;
378 ++NumRegisteredSignals;
381 for (
auto S : IntSigs)
382 registerHandler(S, SignalKind::IsKill);
383 for (
auto S : KillSigs)
384 registerHandler(S, SignalKind::IsKill);
385 if (OneShotPipeSignalFunction)
386 registerHandler(SIGPIPE, SignalKind::IsKill);
387 for (
auto S : InfoSigs)
388 registerHandler(S, SignalKind::IsInfo);
393 for (
unsigned i = 0, e = NumRegisteredSignals.load(); i != e; ++i) {
394 sigaction(RegisteredSignalInfo[i].SigNo, &RegisteredSignalInfo[i].SA,
396 --NumRegisteredSignals;
401static void RemoveFilesToRemove() {
402 FileToRemoveList::removeAllFiles(FilesToRemove);
409 int Sig = (int)Context;
412 InfoSignalHandler(Sig);
416 RemoveFilesToRemove();
425static void SignalHandler(
int Sig, siginfo_t *Info,
void *Context) {
434 sigfillset(&SigMask);
435 sigprocmask(SIG_UNBLOCK, &SigMask,
nullptr);
438 RemoveFilesToRemove();
441 if (
auto OldOneShotPipeFunction =
442 OneShotPipeSignalFunction.exchange(
nullptr))
443 return OldOneShotPipeFunction();
447 if (
auto OldInterruptFunction = InterruptFunction.exchange(
nullptr))
448 return OldInterruptFunction();
450 if (Sig == SIGPIPE || IsIntSig) {
464 if (Sig == SIGILL || Sig == SIGFPE || Sig == SIGTRAP)
468#if defined(__linux__)
474 syscall(SYS_rt_tgsigqueueinfo, getpid(), syscall(SYS_gettid), Sig, Info);
475 if (retval != 0 && errno == EPERM)
480 if (Info->si_pid != getpid() && Info->si_pid != 0)
485static void SignalHandlerTerminate(
int Sig, siginfo_t *Info,
void *Context) {
486 SignalHandler(Sig, Info, Context);
494static void InfoSignalHandler(
int Sig) {
496 if (SignalHandlerFunctionType CurrentInfoFunction = InfoSignalFunction)
497 CurrentInfoFunction();
500static void InfoSignalHandlerTerminate(
int Sig) {
501 InfoSignalHandler(Sig);
503 if (Sig == SIGUSR1) {
513 RemoveFilesToRemove();
517 InterruptFunction.exchange(IF);
522 InfoSignalFunction.exchange(Handler);
527 OneShotPipeSignalFunction.exchange(Handler);
540 *FilesToRemoveCleanup;
541 FileToRemoveList::insert(FilesToRemove,
Filename.str());
548 FileToRemoveList::erase(FilesToRemove,
Filename.str());
555 bool NeedsPOSIXUtilitySignalHandling) {
558 RegisterHandlers(NeedsPOSIXUtilitySignalHandling);
561#if ENABLE_BACKTRACES && defined(HAVE_BACKTRACE) && \
562 (defined(__linux__) || defined(__FreeBSD__) || \
563 defined(__FreeBSD_kernel__) || defined(__NetBSD__) || \
564 defined(__OpenBSD__) || defined(__DragonFly__))
565struct DlIteratePhdrData {
569 const char **modules;
571 const char *main_exec_name;
574static int dl_iterate_phdr_cb(dl_phdr_info *
info,
size_t size,
void *arg) {
575 DlIteratePhdrData *
data = (DlIteratePhdrData *)arg;
578 for (
int i = 0; i <
info->dlpi_phnum; i++) {
579 const auto *phdr = &
info->dlpi_phdr[i];
580 if (phdr->p_type != PT_LOAD)
582 intptr_t beg =
info->dlpi_addr + phdr->p_vaddr;
583 intptr_t
end = beg + phdr->p_memsz;
584 for (
int j = 0;
j <
data->depth;
j++) {
585 if (
data->modules[j])
587 intptr_t addr = (intptr_t)
data->StackTrace[j];
588 if (beg <= addr && addr < end) {
590 data->offsets[
j] = addr -
info->dlpi_addr;
597#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
598#if !defined(HAVE_BACKTRACE)
599#error DebugLoc origin-tracking currently requires `backtrace()`.
603template <
unsigned long MaxDepth>
604int getStackTrace(std::array<void *, MaxDepth> &StackTrace) {
605 return backtrace(StackTrace.data(), MaxDepth);
607template int getStackTrace<16ul>(std::array<void *, 16ul> &);
615 const char **Modules, intptr_t *Offsets,
616 const char *MainExecutableName,
618 DlIteratePhdrData
data = {StackTrace,
Depth,
true,
619 Modules,
Offsets, MainExecutableName};
620 dl_iterate_phdr(dl_iterate_phdr_cb, &
data);
624class DSOMarkupPrinter {
626 const char *MainExecutableName;
627 size_t ModuleCount = 0;
632 : OS(OS), MainExecutableName(MainExecutableName) {}
635 void printDSOMarkup(dl_phdr_info *Info) {
636 bool WasFirst = IsFirst;
641 OS <<
format(
"{{{module:%d:%s:elf:", ModuleCount,
642 WasFirst ? MainExecutableName : Info->dlpi_name);
647 for (
int I = 0;
I < Info->dlpi_phnum;
I++) {
648 const auto *Phdr = &Info->dlpi_phdr[
I];
649 if (Phdr->p_type != PT_LOAD)
651 uintptr_t StartAddress = Info->dlpi_addr + Phdr->p_vaddr;
652 uintptr_t ModuleRelativeAddress = Phdr->p_vaddr;
653 std::array<char, 4> ModeStr = modeStrFromFlags(Phdr->p_flags);
654 OS <<
format(
"{{{mmap:%#016x:%#x:load:%d:%s:%#016x}}}\n", StartAddress,
655 Phdr->p_memsz, ModuleCount, &ModeStr[0],
656 ModuleRelativeAddress);
663 static int printDSOMarkup(dl_phdr_info *Info,
size_t Size,
void *Arg) {
664 static_cast<DSOMarkupPrinter *
>(Arg)->printDSOMarkup(Info);
671 for (
int I = 0;
I < Info->dlpi_phnum;
I++) {
672 const auto *Phdr = &Info->dlpi_phdr[
I];
673 if (Phdr->p_type != PT_NOTE)
677 reinterpret_cast<const uint8_t *
>(Info->dlpi_addr + Phdr->p_vaddr),
679 while (Notes.size() > 12) {
681 Notes = Notes.drop_front(4);
683 Notes = Notes.drop_front(4);
685 Notes = Notes.drop_front(4);
688 auto CurPos =
reinterpret_cast<uintptr_t>(Notes.data());
691 if (BytesUntilDesc >= Notes.size())
693 Notes = Notes.drop_front(BytesUntilDesc);
696 CurPos =
reinterpret_cast<uintptr_t>(Notes.data());
699 if (BytesUntilNextNote > Notes.size())
701 Notes = Notes.drop_front(BytesUntilNextNote);
703 if (Type == 3 &&
Name.size() >= 3 &&
704 Name[0] ==
'G' && Name[1] ==
'N' && Name[2] ==
'U')
713 std::array<char, 4> modeStrFromFlags(
uint32_t Flags) {
714 std::array<char, 4>
Mode;
715 char *Cur = &
Mode[0];
728 const char *MainExecutableName) {
729 OS <<
"{{{reset}}}\n";
730 DSOMarkupPrinter MP(OS, MainExecutableName);
731 dl_iterate_phdr(DSOMarkupPrinter::printDSOMarkup, &MP);
735#elif ENABLE_BACKTRACES && defined(__APPLE__) && defined(__LP64__)
737 const char **Modules, intptr_t *Offsets,
738 const char *MainExecutableName,
740 uint32_t NumImgs = _dyld_image_count();
741 for (
uint32_t ImageIndex = 0; ImageIndex < NumImgs; ImageIndex++) {
742 const char *
Name = _dyld_get_image_name(ImageIndex);
743 intptr_t Slide = _dyld_get_image_vmaddr_slide(ImageIndex);
745 (
const struct mach_header_64 *)_dyld_get_image_header(ImageIndex);
748 auto Cmd = (
const struct load_command *)(&Header[1]);
749 for (
uint32_t CmdNum = 0; CmdNum < Header->ncmds; ++CmdNum) {
750 uint32_t BaseCmd = Cmd->cmd & ~LC_REQ_DYLD;
751 if (BaseCmd == LC_SEGMENT_64) {
752 auto CmdSeg64 = (
const struct segment_command_64 *)Cmd;
753 for (
int j = 0;
j <
Depth;
j++) {
756 intptr_t Addr = (intptr_t)StackTrace[j];
757 if ((intptr_t)CmdSeg64->vmaddr + Slide <= Addr &&
758 Addr < intptr_t(CmdSeg64->vmaddr + CmdSeg64->vmsize + Slide)) {
764 Cmd = (
const load_command *)(((
const char *)Cmd) + (Cmd->cmdsize));
771 const char *MainExecutableName) {
778 const char **Modules, intptr_t *Offsets,
779 const char *MainExecutableName,
785 const char *MainExecutableName) {
790#if ENABLE_BACKTRACES && defined(HAVE__UNWIND_BACKTRACE)
791static int unwindBacktrace(
void **StackTrace,
int MaxEntries) {
798 auto HandleFrame = [&](_Unwind_Context *Context) -> _Unwind_Reason_Code {
800 void *IP = (
void *)_Unwind_GetIP(Context);
802 return _URC_END_OF_STACK;
804 assert(Entries < MaxEntries &&
"recursively called after END_OF_STACK?");
806 StackTrace[Entries] = IP;
808 if (++Entries == MaxEntries)
809 return _URC_END_OF_STACK;
810 return _URC_NO_REASON;
814 [](_Unwind_Context *Context,
void *Handler) {
815 return (*
static_cast<decltype(HandleFrame) *
>(Handler))(Context);
817 static_cast<void *
>(&HandleFrame));
818 return std::max(Entries, 0);
822#if ENABLE_BACKTRACES && defined(__MVS__)
825 constexpr size_t MAX_ENTRY_NAME = UINT16_MAX;
827 constexpr size_t MAX_OTHER = 8;
828 int32_t dsa_format = -1;
829 void *caaptr = _gtca();
831 char compile_unit_name[MAX_OTHER];
832 void *compile_unit_address;
833 void *call_instruction_address =
nullptr;
834 char entry_name[MAX_ENTRY_NAME];
836 void *callers_instruction_address;
837 void *callers_dsaptr;
838 int32_t callers_dsa_format;
839 char statement_id[MAX_OTHER];
841 int32_t main_program;
847 void *dsaptr =
static_cast<char *
>(__builtin_frame_address(0)) - 2048;
849 OS <<
" DSA Adr EP +EP DSA "
853 int32_t compile_unit_name_length =
sizeof(compile_unit_name);
854 int32_t entry_name_length =
sizeof(entry_name);
855 int32_t statement_id_length =
sizeof(statement_id);
859 __CELQTBCK(&dsaptr, &dsa_format, &caaptr, &member_id, &compile_unit_name[0],
860 &compile_unit_name_length, &compile_unit_address,
861 &call_instruction_address, &entry_name[0], &entry_name_length,
862 &entry_address, &callers_instruction_address, &callers_dsaptr,
863 &callers_dsa_format, &statement_id[0], &statement_id_length,
864 &cibptr, &main_program, &fc);
866 OS <<
format(
"error: CELQTBCK returned severity %d message %d\n",
867 fc.tok_sev, fc.tok_msgno);
873 reinterpret_cast<uintptr_t>(entry_address);
874 OS <<
format(
" %3d. 0x%016lX",
count, call_instruction_address);
875 OS <<
format(
" 0x%016lX +0x%08lX 0x%016lX", entry_address, diff, dsaptr);
879 OS <<
' ' << Str <<
'\n';
882 if (callers_dsaptr) {
883 dsaptr = callers_dsaptr;
884 dsa_format = callers_dsa_format;
885 call_instruction_address = callers_instruction_address;
902 static void *StackTrace[256];
904#if defined(HAVE_BACKTRACE)
907 depth = backtrace(StackTrace,
static_cast<int>(std::size(StackTrace)));
909#if defined(HAVE__UNWIND_BACKTRACE)
913 unwindBacktrace(StackTrace,
static_cast<int>(std::size(StackTrace)));
925 OS <<
"Stack dump without symbol names (ensure you have llvm-symbolizer in "
926 "your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point "
928#if HAVE_DLOPEN && !defined(_AIX)
930 for (
int i = 0; i < depth; ++i) {
933 if (dladdr(StackTrace[i], &dlinfo) == 0) {
936 const char *
name = strrchr(dlinfo.dli_fname,
'/');
939 nwidth = strlen(dlinfo.dli_fname);
941 nwidth = strlen(
name) - 1;
944 width = std::max(nwidth, width);
947 for (
int i = 0; i < depth; ++i) {
952 if (dladdr(StackTrace[i], &dlinfo) == 0) {
953 OS <<
format(
" %-*s", width,
static_cast<const char *
>(
"(error)"));
954 dlinfo.dli_sname =
nullptr;
956 const char *
name = strrchr(dlinfo.dli_fname,
'/');
958 OS <<
format(
" %-*s", width, dlinfo.dli_fname);
963 OS <<
format(
" %#0*lx", (
int)(
sizeof(
void *) * 2) + 2,
964 (
unsigned long)StackTrace[i]);
966 if (dlinfo.dli_sname !=
nullptr) {
972 OS << dlinfo.dli_sname;
975 OS <<
format(
" + %tu", (
static_cast<const char *
>(StackTrace[i]) -
976 static_cast<const char *
>(dlinfo.dli_saddr)));
980#elif defined(HAVE_BACKTRACE)
987static void PrintStackTraceSignalHandler(
void *) {
996 bool DisableCrashReporting) {
1001#if defined(__APPLE__) && ENABLE_CRASH_OVERRIDES
1003 if (DisableCrashReporting || getenv(
"LLVM_DISABLE_CRASH_REPORT")) {
1004 mach_port_t
self = mach_task_self();
1006 exception_mask_t
mask = EXC_MASK_CRASH;
1008 kern_return_t ret = task_set_exception_ports(
1009 self,
mask, MACH_PORT_NULL,
1010 EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static constexpr unsigned long long mask(BlockVerifier::State S)
#define LLVM_ATTRIBUTE_USED
This file provides utility functions for converting between EBCDIC-1047 and UTF-8.
This file contains definitions of exit codes for exit() function.
static constexpr StringLiteral Filename
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file 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.
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)
static void insertSignalHandler(sys::SignalHandlerCallback FnPtr, void *Cookie)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
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...
Represent a constant reference to a string, i.e.
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
This class implements an extremely fast bulk output stream that can only output to a stream.
LLVM_ABI void convertToUTF8(StringRef Source, SmallVectorImpl< char > &Result)
constexpr size_t NameSize
SmallVector< uint8_t, 10 > BuildID
A build ID in binary form.
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
ScopedSetting scopedDisable()
std::lock_guard< SmartMutex< mt_only > > SmartScopedLock
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()
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
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.
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
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.
LLVM_ATTRIBUTE_RETURNS_NONNULL void * safe_malloc(size_t Sz)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
A utility class that uses RAII to save and restore the value of a variable.