Skip to content

Commit e065841

Browse files
authored
[asan] Install pthread_atfork (#75290)
This prevents deadlocks in forked process if parent had more then one running threads.
1 parent 12af9c8 commit e065841

File tree

6 files changed

+32
-1
lines changed

6 files changed

+32
-1
lines changed

compiler-rt/lib/asan/asan_fuchsia.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,8 @@ void FlushUnneededASanShadowMemory(uptr p, uptr size) {
240240
// So this doesn't install any atexit hook like on other platforms.
241241
void InstallAtExitCheckLeaks() {}
242242

243+
void InstallAtForkHandler() {}
244+
243245
} // namespace __asan
244246

245247
namespace __lsan {

compiler-rt/lib/asan/asan_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ void *AsanDlSymNext(const char *sym);
126126
bool HandleDlopenInit();
127127

128128
void InstallAtExitCheckLeaks();
129+
void InstallAtForkHandler();
129130

130131
#define ASAN_ON_ERROR() \
131132
if (&__asan_on_error) \

compiler-rt/lib/asan/asan_posix.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,30 @@ void PlatformTSDDtor(void *tsd) {
148148
}
149149
#endif
150150

151+
void InstallAtForkHandler() {
152+
auto before = []() {
153+
if (CAN_SANITIZE_LEAKS) {
154+
__lsan::LockGlobal();
155+
}
156+
// `_lsan` functions defined regardless of `CAN_SANITIZE_LEAKS` and lock the
157+
// stuff we need.
158+
__lsan::LockThreads();
159+
__lsan::LockAllocator();
160+
StackDepotLockAll();
161+
};
162+
auto after = []() {
163+
StackDepotUnlockAll();
164+
// `_lsan` functions defined regardless of `CAN_SANITIZE_LEAKS` and unlock
165+
// the stuff we need.
166+
__lsan::UnlockAllocator();
167+
__lsan::UnlockThreads();
168+
if (CAN_SANITIZE_LEAKS) {
169+
__lsan::UnlockGlobal();
170+
}
171+
};
172+
pthread_atfork(before, after, after);
173+
}
174+
151175
void InstallAtExitCheckLeaks() {
152176
if (CAN_SANITIZE_LEAKS) {
153177
if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) {

compiler-rt/lib/asan/asan_rtl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,8 @@ static bool AsanInitInternal() {
493493
InstallAtExitCheckLeaks();
494494
}
495495

496+
InstallAtForkHandler();
497+
496498
#if CAN_SANITIZE_UB
497499
__ubsan::InitAsPlugin();
498500
#endif

compiler-rt/lib/asan/asan_win.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,8 @@ void InitializePlatformInterceptors() {
203203

204204
void InstallAtExitCheckLeaks() {}
205205

206+
void InstallAtForkHandler() {}
207+
206208
void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {
207209
UNIMPLEMENTED();
208210
}

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, hwasan
3+
// UNSUPPORTED: hwasan
44

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

0 commit comments

Comments
 (0)