mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-25 13:24:46 +00:00
Support: Add CrashRecoveryContext helper object.
- Designed as a simple wrapper to allow clients to attempt to catch crashes (memory errors, assertion violations, etc.) and do some kind of recovery. - Currently doesn't actually attempt to catch crashes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@109586 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
88
lib/Support/CrashRecoveryContext.cpp
Normal file
88
lib/Support/CrashRecoveryContext.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
//===--- CrashRecoveryContext.cpp - Crash Recovery ------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Support/CrashRecoveryContext.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include <setjmp.h>
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
struct CrashRecoveryContextImpl;
|
||||
|
||||
struct CrashRecoveryContextImpl {
|
||||
std::string Backtrace;
|
||||
::jmp_buf JumpBuffer;
|
||||
volatile unsigned Failed : 1;
|
||||
|
||||
public:
|
||||
CrashRecoveryContextImpl() : Failed(false) {}
|
||||
|
||||
void HandleCrash() {
|
||||
assert(!Failed && "Crash recovery context already failed!");
|
||||
Failed = true;
|
||||
|
||||
// FIXME: Stash the backtrace.
|
||||
|
||||
// Jump back to the RunSafely we were called under.
|
||||
longjmp(JumpBuffer, 1);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
static bool gCrashRecoveryEnabled = false;
|
||||
|
||||
CrashRecoveryContext::~CrashRecoveryContext() {
|
||||
CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl;
|
||||
delete CRCI;
|
||||
}
|
||||
|
||||
void CrashRecoveryContext::Enable() {
|
||||
if (gCrashRecoveryEnabled)
|
||||
return;
|
||||
|
||||
gCrashRecoveryEnabled = true;
|
||||
}
|
||||
|
||||
void CrashRecoveryContext::Disable() {
|
||||
if (!gCrashRecoveryEnabled)
|
||||
return;
|
||||
|
||||
gCrashRecoveryEnabled = false;
|
||||
}
|
||||
|
||||
bool CrashRecoveryContext::RunSafely(void (*Fn)(void*), void *UserData) {
|
||||
// If crash recovery is disabled, do nothing.
|
||||
if (gCrashRecoveryEnabled) {
|
||||
assert(!Impl && "Crash recovery context already initialized!");
|
||||
CrashRecoveryContextImpl *CRCI = new CrashRecoveryContextImpl;
|
||||
Impl = CRCI;
|
||||
|
||||
if (setjmp(CRCI->JumpBuffer) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Fn(UserData);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CrashRecoveryContext::HandleCrash() {
|
||||
CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl;
|
||||
assert(CRCI && "Crash recovery context never initialized!");
|
||||
CRCI->HandleCrash();
|
||||
}
|
||||
|
||||
const std::string &CrashRecoveryContext::getBacktrace() const {
|
||||
CrashRecoveryContextImpl *CRC = (CrashRecoveryContextImpl *) Impl;
|
||||
assert(CRC && "Crash recovery context never initialized!");
|
||||
assert(CRC->Failed && "No crash was detected!");
|
||||
return CRC->Backtrace;
|
||||
}
|
Reference in New Issue
Block a user