[llvm] [Support] Don't take a lock in CrashRecoverySignalHandler (PR #219529)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 28 10:19:28 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-support
Author: Jonas Devlieghere (JDevlieghere)
<details>
<summary>Changes</summary>
Disable() locks a mutex with static storage duration, which is not safe from a signal handler. When the signal arrives during exit(), after static destructors have run, the mutex is already destroyed, causing pthread_mutex_lock returns EINVAL and in turn causing libc++ to throw.
To make matters worse, without exceptions, the throw becomes a std::terminate, which happens before uninstallExceptionOrSignalHandlers. Because the signal handler is installed without SA_RESETHAND, every call to abort() re-enters the handler and throws again.
Inline the two statements Disable() performs. Racing with another thread here doesn't matter, as the previous comment noted.
---
Full diff: https://github.com/llvm/llvm-project/pull/219529.diff
1 Files Affected:
- (modified) llvm/lib/Support/CrashRecoveryContext.cpp (+6-2)
``````````diff
diff --git a/llvm/lib/Support/CrashRecoveryContext.cpp b/llvm/lib/Support/CrashRecoveryContext.cpp
index 493ba951fd3e1..c4bad21fcefc3 100644
--- a/llvm/lib/Support/CrashRecoveryContext.cpp
+++ b/llvm/lib/Support/CrashRecoveryContext.cpp
@@ -369,8 +369,12 @@ static void CrashRecoverySignalHandler(int Signal) {
// that the enclosing application will terminate soon, and we won't want to
// attempt crash recovery again.
//
- // This call of Disable isn't thread safe, but it doesn't actually matter.
- CrashRecoveryContext::Disable();
+ // Uninstall directly rather than through Disable(): a signal handler must
+ // not take a lock, and a lock with static storage duration may already be
+ // destroyed by the time a signal is delivered during exit(). Racing with
+ // another thread here doesn't matter.
+ gCrashRecoveryEnabled = false;
+ uninstallExceptionOrSignalHandlers();
raise(Signal);
// The signal will be thrown once the signal mask is restored.
``````````
</details>
https://github.com/llvm/llvm-project/pull/219529
More information about the llvm-commits
mailing list