[PATCH] D11770: Allow nested CrashRecoveryContexts.
Nico Weber
thakis at chromium.org
Wed Aug 5 10:35:43 PDT 2015
thakis created this revision.
thakis added a reviewer: akyrtzi.
thakis added a subscriber: llvm-commits.
libclang uses a CrashRecoveryContext, and building a module does too. If a module gets built through libclang, nested CrashRecoveryContexts are used. They work fine with threads as things are stored in ThreadLocal variables, but in LLVM_ENABLE_THREADS=OFF builds the two recovery contexts would write to the same globals.
To fix, keep active CrashRecoveryContextImpls in a list and have the global point to the innermost one, and do something similar for tlIsRecoveringFromCrash.
Necessary (but not sufficient) for PR11974 and PR20325
http://reviews.llvm.org/D11770
Files:
include/llvm/Support/CrashRecoveryContext.h
lib/Support/CrashRecoveryContext.cpp
Index: include/llvm/Support/CrashRecoveryContext.h
===================================================================
--- include/llvm/Support/CrashRecoveryContext.h
+++ include/llvm/Support/CrashRecoveryContext.h
@@ -39,8 +39,6 @@
///
/// ... no crash was detected ...
/// }
-///
-/// Crash recovery contexts may not be nested.
class CrashRecoveryContext {
void *Impl;
CrashRecoveryContextCleanup *head;
Index: lib/Support/CrashRecoveryContext.cpp
===================================================================
--- lib/Support/CrashRecoveryContext.cpp
+++ lib/Support/CrashRecoveryContext.cpp
@@ -24,6 +24,8 @@
sys::ThreadLocal<const CrashRecoveryContextImpl> > CurrentContext;
struct CrashRecoveryContextImpl {
+ const CrashRecoveryContextImpl *Next;
+
CrashRecoveryContext *CRC;
std::string Backtrace;
::jmp_buf JumpBuffer;
@@ -34,21 +36,26 @@
CrashRecoveryContextImpl(CrashRecoveryContext *CRC) : CRC(CRC),
Failed(false),
SwitchedThread(false) {
+ Next = CurrentContext->get();
CurrentContext->set(this);
}
~CrashRecoveryContextImpl() {
if (!SwitchedThread)
- CurrentContext->erase();
+ CurrentContext->set(Next);
}
/// \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 setSwitchedThread() {
+#if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0
+ SwitchedThread = true;
+#endif
+ }
void HandleCrash() {
// Eliminate the current context entry, to avoid re-entering in case the
// cleanup code crashes.
- CurrentContext->erase();
+ CurrentContext->set(Next);
assert(!Failed && "Crash recovery context already failed!");
Failed = true;
@@ -65,23 +72,24 @@
static ManagedStatic<sys::Mutex> gCrashRecoveryContextMutex;
static bool gCrashRecoveryEnabled = false;
-static ManagedStatic<sys::ThreadLocal<const CrashRecoveryContextCleanup> >
+static ManagedStatic<sys::ThreadLocal<const CrashRecoveryContext>>
tlIsRecoveringFromCrash;
CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() {}
CrashRecoveryContext::~CrashRecoveryContext() {
// Reclaim registered resources.
CrashRecoveryContextCleanup *i = head;
- tlIsRecoveringFromCrash->set(head);
+ const CrashRecoveryContext *PC = tlIsRecoveringFromCrash->get();
+ tlIsRecoveringFromCrash->set(this);
while (i) {
CrashRecoveryContextCleanup *tmp = i;
i = tmp->next;
tmp->cleanupFired = true;
tmp->recoverResources();
delete tmp;
}
- tlIsRecoveringFromCrash->erase();
+ tlIsRecoveringFromCrash->set(PC);
CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl;
delete CRCI;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D11770.31369.patch
Type: text/x-patch
Size: 2913 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150805/93aa6acb/attachment.bin>
More information about the llvm-commits
mailing list