diff options
author | Vitaly Buka <vitalybuka@google.com> | 2023-12-13 13:09:36 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-13 13:09:36 -0800 |
commit | 14d7e0bb0f75066da5d2eff718b6d59215a02077 (patch) | |
tree | 93d45d260321f36988906f414731275955c0ec7f | |
parent | e8f43883a073f4ef71e7f724143e068099649952 (diff) | |
download | llvm-14d7e0bb0f75066da5d2eff718b6d59215a02077.zip llvm-14d7e0bb0f75066da5d2eff718b6d59215a02077.tar.gz llvm-14d7e0bb0f75066da5d2eff718b6d59215a02077.tar.bz2 |
[lsan] Install `pthread_atfork` (#75281)
This prevents deadlocks in forked process on essencial
runtime components.
-rw-r--r-- | compiler-rt/lib/lsan/lsan.cpp | 1 | ||||
-rw-r--r-- | compiler-rt/lib/lsan/lsan.h | 1 | ||||
-rw-r--r-- | compiler-rt/lib/lsan/lsan_common.cpp | 3 | ||||
-rw-r--r-- | compiler-rt/lib/lsan/lsan_common.h | 4 | ||||
-rw-r--r-- | compiler-rt/lib/lsan/lsan_fuchsia.cpp | 1 | ||||
-rw-r--r-- | compiler-rt/lib/lsan/lsan_posix.cpp | 18 | ||||
-rw-r--r-- | compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.c | 2 |
7 files changed, 29 insertions, 1 deletions
diff --git a/compiler-rt/lib/lsan/lsan.cpp b/compiler-rt/lib/lsan/lsan.cpp index 6b22360..7a27b60 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 757edec..0074ad5 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 8b1af5b..e24839c 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 d3e7683..c598b62 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 4edac97..ba59bc9 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 732b8af..3677f01 100644 --- a/compiler-rt/lib/lsan/lsan_posix.cpp +++ b/compiler-rt/lib/lsan/lsan_posix.cpp @@ -14,6 +14,8 @@ #include "sanitizer_common/sanitizer_platform.h" #if SANITIZER_POSIX +# include <pthread.h> + # include "lsan.h" # include "lsan_allocator.h" # include "lsan_thread.h" @@ -98,6 +100,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.c b/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.c index eaa1a04..7592269 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.c +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.c @@ -1,6 +1,6 @@ // RUN: %clang -O0 %s -o %t && %env_tool_opts=die_after_fork=0 %run %t -// UNSUPPORTED: asan, lsan, hwasan +// UNSUPPORTED: asan, hwasan // The test uses pthread barriers which are not available on Darwin. // UNSUPPORTED: darwin |