Skip to content

Commit

Permalink
[Support/CrashRecoveryContext] Make sure CrashRecoveryContext does no…
Browse files Browse the repository at this point in the history
…t clear the thread-local "CurrentContext"

in the "parent" thread, when we are using CrashRecoveryContext::RunSafelyOnThread.

When using CrashRecoveryContext::RunSafelyOnThread, we would set a CrashRecoveryContextImpl* to a thread-local variable
for the "child" thread, but CrashRecoveryContext would erroneously clear it in the "parent" thread.

The result was that if CrashRecoveryContext::RunSafelyOnThread was called again in the "child" thread it would mess up
crash-recovery for its parent.

A test for this will be added in the clang repository.
rdar://14204560

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184380 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
akyrtzi committed Jun 19, 2013
1 parent 228546b commit 4e91fa3
Showing 1 changed file with 11 additions and 2 deletions.
13 changes: 11 additions & 2 deletions lib/Support/CrashRecoveryContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,23 @@ struct CrashRecoveryContextImpl {
std::string Backtrace;
::jmp_buf JumpBuffer;
volatile unsigned Failed : 1;
unsigned SwitchedThread : 1;

public:
CrashRecoveryContextImpl(CrashRecoveryContext *CRC) : CRC(CRC),
Failed(false) {
Failed(false),
SwitchedThread(false) {
CurrentContext.set(this);
}
~CrashRecoveryContextImpl() {
CurrentContext.erase();
if (!SwitchedThread)
CurrentContext.erase();
}

/// \brief Called when the separate crash-recovery thread was finished, to
/// indicate that we don't need to clear the thread-local CurrentContext.
void setSwitchedThread() { SwitchedThread = true; }

void HandleCrash() {
// Eliminate the current context entry, to avoid re-entering in case the
// cleanup code crashes.
Expand Down Expand Up @@ -342,5 +349,7 @@ bool CrashRecoveryContext::RunSafelyOnThread(void (*Fn)(void*), void *UserData,
unsigned RequestedStackSize) {
RunSafelyOnThreadInfo Info = { Fn, UserData, this, false };
llvm_execute_on_thread(RunSafelyOnThread_Dispatch, &Info, RequestedStackSize);
if (CrashRecoveryContextImpl *CRC = (CrashRecoveryContextImpl *)Impl)
CRC->setSwitchedThread();
return Info.Result;
}

0 comments on commit 4e91fa3

Please sign in to comment.