11 #include "llvm/Config/config.h"
21 struct CrashRecoveryContextImpl;
26 struct CrashRecoveryContextImpl {
31 const CrashRecoveryContextImpl *Next;
35 volatile unsigned Failed : 1;
36 unsigned SwitchedThread : 1;
41 SwitchedThread(
false) {
42 Next = CurrentContext->get();
43 CurrentContext->set(
this);
45 ~CrashRecoveryContextImpl() {
47 CurrentContext->set(Next);
52 void setSwitchedThread() {
53 #if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0
54 SwitchedThread =
true;
61 CurrentContext->set(Next);
63 assert(!Failed &&
"Crash recovery context already failed!");
69 longjmp(JumpBuffer, 1);
97 CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl;
109 const CrashRecoveryContextImpl *CRCI = CurrentContext->get();
122 cleanup->next = head;
130 if (cleanup == head) {
131 head = cleanup->next;
133 head->prev =
nullptr;
136 cleanup->prev->next = cleanup->next;
138 cleanup->next->prev = cleanup->prev;
165 static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo)
168 const CrashRecoveryContextImpl *CRCI = CurrentContext->get();
174 return EXCEPTION_CONTINUE_SEARCH;
181 const_cast<CrashRecoveryContextImpl*
>(CRCI)->HandleCrash();
207 PVOID handle = ::AddVectoredExceptionHandler(1, ExceptionHandler);
208 sCurrentExceptionHandle.set(handle);
219 PVOID currentHandle =
const_cast<PVOID
>(sCurrentExceptionHandle.get());
222 ::RemoveVectoredExceptionHandler(currentHandle);
225 sCurrentExceptionHandle.set(NULL);
245 { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGTRAP };
251 const CrashRecoveryContextImpl *CRCI = CurrentContext->get();
273 sigemptyset(&SigMask);
274 sigaddset(&SigMask, Signal);
275 sigprocmask(SIG_UNBLOCK, &SigMask,
nullptr);
278 const_cast<CrashRecoveryContextImpl*
>(CRCI)->HandleCrash();
290 struct sigaction Handler;
292 Handler.sa_flags = 0;
293 sigemptyset(&Handler.sa_mask);
318 assert(!Impl &&
"Crash recovery context already initialized!");
319 CrashRecoveryContextImpl *CRCI =
new CrashRecoveryContextImpl(
this);
322 if (setjmp(CRCI->JumpBuffer) != 0) {
332 CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl;
333 assert(CRCI &&
"Crash recovery context never initialized!");
340 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
346 return getpriority(PRIO_DARWIN_THREAD, 0) == 1;
353 struct RunSafelyOnThreadInfo {
356 bool UseBackgroundPriority;
362 RunSafelyOnThreadInfo *Info =
363 reinterpret_cast<RunSafelyOnThreadInfo*
>(UserData);
365 if (Info->UseBackgroundPriority)
368 Info->Result = Info->CRC->RunSafely(Info->Fn);
371 unsigned RequestedStackSize) {
373 RunSafelyOnThreadInfo Info = { Fn,
this, UseBackgroundPriority,
false };
375 if (CrashRecoveryContextImpl *CRC = (CrashRecoveryContextImpl *)Impl)
376 CRC->setSwitchedThread();
ThreadLocal - A class used to abstract thread-local storage.
static const int Signals[]
An efficient, type-erasing, non-owning reference to a callable.
static CrashRecoveryContext * GetCurrent()
Return the active context, if the code is currently executing in a thread which is in a protected con...
static bool hasThreadBackgroundPriority()
static void cleanup(BlockFrequencyInfoImplBase &BFI)
Clear all memory not needed downstream.
void HandleCrash()
Explicitly trigger a crash recovery in the current process, and return failure from RunSafely()...
void unregisterCleanup(CrashRecoveryContextCleanup *cleanup)
virtual ~CrashRecoveryContextCleanup()
Function Alias Analysis false
static void Enable()
Enable crash recovery.
static ManagedStatic< sys::Mutex > gCrashRecoveryContextMutex
bool RunSafelyOnThread(function_ref< void()>, unsigned RequestedStackSize=0)
Execute the provide callback function (with the given arguments) in a protected context which is run ...
void registerCleanup(CrashRecoveryContextCleanup *cleanup)
static void CrashRecoverySignalHandler(int Signal)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void llvm_execute_on_thread(void(*UserFn)(void *), void *UserData, unsigned RequestedStackSize=0)
llvm_execute_on_thread - Execute the given UserFn on a separate thread, passing it the provided UserD...
virtual void recoverResources()=0
static ManagedStatic< sys::ThreadLocal< const CrashRecoveryContext > > tlIsRecoveringFromCrash
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
static const unsigned NumSignals
bool RunSafely(function_ref< void()> Fn)
Execute the provide callback function (with the given arguments) in a protected context.
Crash recovery helper object.
static void setThreadBackgroundPriority()
static bool gCrashRecoveryEnabled
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
static bool isRecoveringFromCrash()
Return true if the current thread is recovering from a crash.
static void RunSafelyOnThread_Dispatch(void *UserData)
static void Disable()
Disable crash recovery.
static struct sigaction PrevActions[NumSignals]