PrettyStackTraceEntry::PrettyStackTraceEntry() { // The first time this is called, we register the crash printer. static bool HandlerRegistered = RegisterCrashPrinter(); (void)HandlerRegistered; // Link ourselves. NextEntry = PrettyStackTraceHead.get(); PrettyStackTraceHead.set(this); }
/// PrintCurStackTrace - Print the current stack trace to the specified stream. static void PrintCurStackTrace(raw_ostream &OS) { // Don't print an empty trace. if (PrettyStackTraceHead.get() == 0) return; // If there are pretty stack frames registered, walk and emit them. OS << "Stack dump:\n"; PrintStack(PrettyStackTraceHead.get(), OS); OS.flush(); }
CrashRecoveryContext::~CrashRecoveryContext() { // Reclaim registered resources. CrashRecoveryContextCleanup *i = head; tlIsRecoveringFromCrash.set(head); while (i) { CrashRecoveryContextCleanup *tmp = i; i = tmp->next; tmp->cleanupFired = true; tmp->recoverResources(); delete tmp; } tlIsRecoveringFromCrash.erase(); CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl; delete CRCI; }
void CrashRecoveryContext::Disable() { sys::ScopedLock L(*gCrashRecoveryContextMutex); if (!gCrashRecoveryEnabled) return; gCrashRecoveryEnabled = false; PVOID currentHandle = const_cast<PVOID>(sCurrentExceptionHandle.get()); if (currentHandle) { // Now we can remove the vectored exception handler from the chain ::RemoveVectoredExceptionHandler(currentHandle); // Reset the handle in our thread-local set. sCurrentExceptionHandle.set(NULL); } }
void CrashRecoveryContext::Enable() { sys::ScopedLock L(*gCrashRecoveryContextMutex); if (gCrashRecoveryEnabled) return; gCrashRecoveryEnabled = true; // We can set up vectored exception handling now. We will install our // handler as the front of the list, though there's no assurances that // it will remain at the front (another call could install itself before // our handler). This 1) isn't likely, and 2) shouldn't cause problems. PVOID handle = ::AddVectoredExceptionHandler(1, ExceptionHandler); sCurrentExceptionHandle.set(handle); }
bool CrashRecoveryContext::isRecoveringFromCrash() { return tlIsRecoveringFromCrash.get() != 0; }
PrettyStackTraceEntry::~PrettyStackTraceEntry() { assert(PrettyStackTraceHead.get() == this && "Pretty stack trace entry destruction is out of order"); PrettyStackTraceHead.set(getNextEntry()); }