mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-10 02:36:06 +00:00
a309dac868
- 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
89 lines
2.2 KiB
C++
89 lines
2.2 KiB
C++
//===--- 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;
|
|
}
|