Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lsan] Install pthread_atfork #75281

Merged
merged 8 commits into from
Dec 13, 2023

Conversation

vitalybuka
Copy link
Collaborator

This prevents deadlocks in forked process on essencial
runtime components.

@llvmbot
Copy link

llvmbot commented Dec 13, 2023

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Vitaly Buka (vitalybuka)

Changes

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 --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.

Copy link

github-actions bot commented Dec 13, 2023

:white_check_mark: With the latest revision this PR passed the C/C++ code formatter.

Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
@vitalybuka vitalybuka changed the base branch from users/vitalybuka/spr/main.lsan-install-pthread_atfork to main December 13, 2023 19:25
@vitalybuka vitalybuka merged commit 14d7e0b into main Dec 13, 2023
7 checks passed
@vitalybuka vitalybuka deleted the users/vitalybuka/spr/lsan-install-pthread_atfork branch December 13, 2023 21:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants