[llvm-branch-commits] [compiler-rt] [lsan] Install `pthread_atfork` (PR #75281)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Dec 12 20:48:58 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-compiler-rt-sanitizer
Author: Vitaly Buka (vitalybuka)
<details>
<summary>Changes</summary>
This prevents deadlocks in forked process on essencial
runtime components.
---
Full diff: https://github.com/llvm/llvm-project/pull/75281.diff
7 Files Affected:
- (modified) compiler-rt/lib/lsan/lsan.cpp (+1)
- (modified) compiler-rt/lib/lsan/lsan.h (+1)
- (modified) compiler-rt/lib/lsan/lsan_common.cpp (+3)
- (modified) compiler-rt/lib/lsan/lsan_common.h (+4)
- (modified) compiler-rt/lib/lsan/lsan_fuchsia.cpp (+1)
- (modified) compiler-rt/lib/lsan/lsan_posix.cpp (+20)
- (modified) compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp (+1-1)
``````````diff
diff --git a/compiler-rt/lib/lsan/lsan.cpp b/compiler-rt/lib/lsan/lsan.cpp
index 6b223603c6a79c..7a27b600f203f7 100644
--- a/compiler-rt/lib/lsan/lsan.cpp
+++ b/compiler-rt/lib/lsan/lsan.cpp
@@ -101,6 +101,7 @@ extern "C" void __lsan_init() {
InstallDeadlySignalHandlers(LsanOnDeadlySignal);
InitializeMainThread();
InstallAtExitCheckLeaks();
+ InstallAtForkHandler();
InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
diff --git a/compiler-rt/lib/lsan/lsan.h b/compiler-rt/lib/lsan/lsan.h
index 757edec8e104f9..0074ad5308785c 100644
--- a/compiler-rt/lib/lsan/lsan.h
+++ b/compiler-rt/lib/lsan/lsan.h
@@ -40,6 +40,7 @@ void InitializeInterceptors();
void ReplaceSystemMalloc();
void LsanOnDeadlySignal(int signo, void *siginfo, void *context);
void InstallAtExitCheckLeaks();
+void InstallAtForkHandler();
#define ENSURE_LSAN_INITED \
do { \
diff --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp
index 8b1af5b629fbce..e24839c984b346 100644
--- a/compiler-rt/lib/lsan/lsan_common.cpp
+++ b/compiler-rt/lib/lsan/lsan_common.cpp
@@ -42,6 +42,9 @@ namespace __lsan {
// also to protect the global list of root regions.
static Mutex global_mutex;
+void LockGlobal() SANITIZER_ACQUIRE(global_mutex) { global_mutex.Lock(); }
+void UnlockGlobal() SANITIZER_RELEASE(global_mutex) { global_mutex.Unlock(); }
+
Flags lsan_flags;
void DisableCounterUnderflow() {
diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h
index d3e768363e93b9..c598b62105873e 100644
--- a/compiler-rt/lib/lsan/lsan_common.h
+++ b/compiler-rt/lib/lsan/lsan_common.h
@@ -120,6 +120,10 @@ void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads);
void LockAllocator();
void UnlockAllocator();
+// Lock/unlock global mutext.
+void LockGlobal();
+void UnlockGlobal();
+
// Returns the address range occupied by the global allocator object.
void GetAllocatorGlobalRange(uptr *begin, uptr *end);
// If p points into a chunk that has been allocated to the user, returns its
diff --git a/compiler-rt/lib/lsan/lsan_fuchsia.cpp b/compiler-rt/lib/lsan/lsan_fuchsia.cpp
index 4edac9757a9c49..ba59bc9b71e332 100644
--- a/compiler-rt/lib/lsan/lsan_fuchsia.cpp
+++ b/compiler-rt/lib/lsan/lsan_fuchsia.cpp
@@ -80,6 +80,7 @@ void GetAllThreadAllocatorCachesLocked(InternalMmapVector<uptr> *caches) {
// On Fuchsia, leak detection is done by a special hook after atexit hooks.
// So this doesn't install any atexit hook like on other platforms.
void InstallAtExitCheckLeaks() {}
+void InstallAtForkHandler() {}
// ASan defines this to check its `halt_on_error` flag.
bool UseExitcodeOnLeak() { return true; }
diff --git a/compiler-rt/lib/lsan/lsan_posix.cpp b/compiler-rt/lib/lsan/lsan_posix.cpp
index d99e1cc0105ef7..7dc4254eb150a3 100644
--- a/compiler-rt/lib/lsan/lsan_posix.cpp
+++ b/compiler-rt/lib/lsan/lsan_posix.cpp
@@ -14,7 +14,11 @@
#include "sanitizer_common/sanitizer_platform.h"
#if SANITIZER_POSIX
+
#include "lsan.h"
+
+#include <pthread.h>
+
#include "lsan_allocator.h"
#include "lsan_thread.h"
#include "sanitizer_common/sanitizer_stacktrace.h"
@@ -98,6 +102,22 @@ void InstallAtExitCheckLeaks() {
Atexit(DoLeakCheck);
}
+void InstallAtForkHandler() {
+ auto before = []() {
+ LockGlobal();
+ LockThreads();
+ LockAllocator();
+ StackDepotLockAll();
+ };
+ auto after = []() {
+ StackDepotUnlockAll();
+ UnlockAllocator();
+ UnlockThreads();
+ UnlockGlobal();
+ };
+ pthread_atfork(before, after, after);
+}
+
} // namespace __lsan
#endif // SANITIZER_POSIX
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp
index e2d67341846c74..833edbdb54bd93 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp
@@ -1,6 +1,6 @@
// RUN: %clangxx -O0 %s -o %t && %env_tool_opts=die_after_fork=0 %run %t
-// UNSUPPORTED: asan, lsan, hwasan
+// UNSUPPORTED: asan, hwasan
// Forking in multithread environment is unsupported. However we already have
// some workarounds, and will add more, so this is the test.
``````````
</details>
https://github.com/llvm/llvm-project/pull/75281
More information about the llvm-branch-commits
mailing list