Skip to content

Commit 14d7e0b

Browse files
authored
[lsan] Install pthread_atfork (#75281)
This prevents deadlocks in forked process on essencial runtime components.
1 parent e8f4388 commit 14d7e0b

File tree

7 files changed

+29
-1
lines changed

7 files changed

+29
-1
lines changed

compiler-rt/lib/lsan/lsan.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ extern "C" void __lsan_init() {
101101
InstallDeadlySignalHandlers(LsanOnDeadlySignal);
102102
InitializeMainThread();
103103
InstallAtExitCheckLeaks();
104+
InstallAtForkHandler();
104105

105106
InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
106107

compiler-rt/lib/lsan/lsan.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ void InitializeInterceptors();
4040
void ReplaceSystemMalloc();
4141
void LsanOnDeadlySignal(int signo, void *siginfo, void *context);
4242
void InstallAtExitCheckLeaks();
43+
void InstallAtForkHandler();
4344

4445
#define ENSURE_LSAN_INITED \
4546
do { \

compiler-rt/lib/lsan/lsan_common.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ namespace __lsan {
4242
// also to protect the global list of root regions.
4343
static Mutex global_mutex;
4444

45+
void LockGlobal() SANITIZER_ACQUIRE(global_mutex) { global_mutex.Lock(); }
46+
void UnlockGlobal() SANITIZER_RELEASE(global_mutex) { global_mutex.Unlock(); }
47+
4548
Flags lsan_flags;
4649

4750
void DisableCounterUnderflow() {

compiler-rt/lib/lsan/lsan_common.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads);
120120
void LockAllocator();
121121
void UnlockAllocator();
122122

123+
// Lock/unlock global mutext.
124+
void LockGlobal();
125+
void UnlockGlobal();
126+
123127
// Returns the address range occupied by the global allocator object.
124128
void GetAllocatorGlobalRange(uptr *begin, uptr *end);
125129
// If p points into a chunk that has been allocated to the user, returns its

compiler-rt/lib/lsan/lsan_fuchsia.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ void GetAllThreadAllocatorCachesLocked(InternalMmapVector<uptr> *caches) {
8080
// On Fuchsia, leak detection is done by a special hook after atexit hooks.
8181
// So this doesn't install any atexit hook like on other platforms.
8282
void InstallAtExitCheckLeaks() {}
83+
void InstallAtForkHandler() {}
8384

8485
// ASan defines this to check its `halt_on_error` flag.
8586
bool UseExitcodeOnLeak() { return true; }

compiler-rt/lib/lsan/lsan_posix.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include "sanitizer_common/sanitizer_platform.h"
1515

1616
#if SANITIZER_POSIX
17+
# include <pthread.h>
18+
1719
# include "lsan.h"
1820
# include "lsan_allocator.h"
1921
# include "lsan_thread.h"
@@ -98,6 +100,22 @@ void InstallAtExitCheckLeaks() {
98100
Atexit(DoLeakCheck);
99101
}
100102

103+
void InstallAtForkHandler() {
104+
auto before = []() {
105+
LockGlobal();
106+
LockThreads();
107+
LockAllocator();
108+
StackDepotLockAll();
109+
};
110+
auto after = []() {
111+
StackDepotUnlockAll();
112+
UnlockAllocator();
113+
UnlockThreads();
114+
UnlockGlobal();
115+
};
116+
pthread_atfork(before, after, after);
117+
}
118+
101119
} // namespace __lsan
102120

103121
#endif // SANITIZER_POSIX

compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %clang -O0 %s -o %t && %env_tool_opts=die_after_fork=0 %run %t
22

3-
// UNSUPPORTED: asan, lsan, hwasan
3+
// UNSUPPORTED: asan, hwasan
44

55
// The test uses pthread barriers which are not available on Darwin.
66
// UNSUPPORTED: darwin

0 commit comments

Comments
 (0)