11 #include "llvm/Config/llvm-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!");
100 CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl;
109 if (!gCrashRecoveryEnabled)
112 const CrashRecoveryContextImpl *CRCI = CurrentContext->get();
122 if (gCrashRecoveryEnabled)
124 gCrashRecoveryEnabled =
true;
130 if (!gCrashRecoveryEnabled)
132 gCrashRecoveryEnabled =
false;
142 cleanup->next = head;
150 if (cleanup == head) {
151 head = cleanup->next;
153 head->prev =
nullptr;
156 cleanup->prev->next = cleanup->next;
158 cleanup->next->prev = cleanup->prev;
163 #if defined(_MSC_VER) 176 if (!gCrashRecoveryEnabled) {
214 static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo)
218 constexpr ULONG DbgPrintExceptionWideC = 0x4001000AL;
219 switch (ExceptionInfo->ExceptionRecord->ExceptionCode)
221 case DBG_PRINTEXCEPTION_C:
222 case DbgPrintExceptionWideC:
224 return EXCEPTION_CONTINUE_EXECUTION;
228 const CrashRecoveryContextImpl *CRCI = CurrentContext->get();
234 return EXCEPTION_CONTINUE_SEARCH;
241 const_cast<CrashRecoveryContextImpl*
>(CRCI)->HandleCrash();
260 PVOID handle = ::AddVectoredExceptionHandler(1, ExceptionHandler);
261 sCurrentExceptionHandle.
set(handle);
265 PVOID currentHandle =
const_cast<PVOID
>(sCurrentExceptionHandle.
get());
268 ::RemoveVectoredExceptionHandler(currentHandle);
271 sCurrentExceptionHandle.
set(NULL);
291 { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGTRAP };
297 const CrashRecoveryContextImpl *CRCI = CurrentContext->get();
319 sigemptyset(&SigMask);
320 sigaddset(&SigMask, Signal);
321 sigprocmask(SIG_UNBLOCK, &SigMask,
nullptr);
324 const_cast<CrashRecoveryContextImpl*
>(CRCI)->HandleCrash();
329 struct sigaction Handler;
331 Handler.sa_flags = 0;
332 sigemptyset(&Handler.sa_mask);
349 if (gCrashRecoveryEnabled) {
350 assert(!Impl &&
"Crash recovery context already initialized!");
351 CrashRecoveryContextImpl *CRCI =
new CrashRecoveryContextImpl(
this);
354 if (
setjmp(CRCI->JumpBuffer) != 0) {
366 CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl;
367 assert(CRCI &&
"Crash recovery context never initialized!");
374 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
380 return getpriority(PRIO_DARWIN_THREAD, 0) == 1;
387 struct RunSafelyOnThreadInfo {
390 bool UseBackgroundPriority;
396 RunSafelyOnThreadInfo *
Info =
397 reinterpret_cast<RunSafelyOnThreadInfo*
>(UserData);
399 if (Info->UseBackgroundPriority)
402 Info->Result = Info->CRC->RunSafely(Info->Fn);
405 unsigned RequestedStackSize) {
407 RunSafelyOnThreadInfo
Info = { Fn,
this, UseBackgroundPriority,
false };
409 if (CrashRecoveryContextImpl *CRC = (CrashRecoveryContextImpl *)Impl)
410 CRC->setSwitchedThread();
This class represents lattice values for constants.
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()
static void Enable()
Enable crash recovery.
Abstract base class of cleanup handlers.
static ManagedStatic< sys::Mutex > gCrashRecoveryContextMutex
Analysis containing CSE Info
T * get()
get - Fetches a pointer to the object associated with the current thread.
bool RunSafelyOnThread(function_ref< void()>, unsigned RequestedStackSize=0)
Execute the provide callback function (with the given arguments) in a protected context which is run ...
static void uninstallExceptionOrSignalHandlers()
void registerCleanup(CrashRecoveryContextCleanup *cleanup)
Register cleanup handler, which is used when the recovery context is finished.
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
testing::Matcher< const detail::ErrorHolder & > Failed()
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 provided callback function (with the given arguments) in a protected context.
static void installExceptionOrSignalHandlers()
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]