[compiler-rt] r372459 - Stop tracking atexit/__cxa_atexit/pthread_atfork allocations in LSan/NetBSD

Kamil Rytarowski via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 21 00:30:42 PDT 2019


Author: kamil
Date: Sat Sep 21 00:30:42 2019
New Revision: 372459

URL: http://llvm.org/viewvc/llvm-project?rev=372459&view=rev
Log:
Stop tracking atexit/__cxa_atexit/pthread_atfork allocations in LSan/NetBSD

Summary:
The atexit(3) and __cxa_atexit() calls allocate internally memory and free on exit,
after executing all callback. This causes false positives as DoLeakCheck() is called
from the atexit handler. In the LSan/ASan tests there are strict checks triggering
false positives here.

Intercept all atexit(3) and __cxa_atexit() calls and disable LSan when calling the
real functions.

Stop tracing allocations in pthread_atfork(3) funtions, as there are performed
internal allocations that are not freed for the time of running StopTheWorld()
code. This avoids false-positives.

The same changes have to be replicated in the ASan and LSan runtime.

Non-NetBSD OSs are not tested and this code is restricted to NetBSD only.

Reviewers: dvyukov, joerg, mgorny, vitalybuka, eugenis

Reviewed By: vitalybuka

Subscribers: jfb, llvm-commits, #sanitizers

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D67331

Modified:
    compiler-rt/trunk/lib/asan/asan_interceptors.cpp
    compiler-rt/trunk/lib/asan/asan_interceptors.h
    compiler-rt/trunk/lib/lsan/lsan_interceptors.cpp
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h

Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cpp?rev=372459&r1=372458&r2=372459&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cpp (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cpp Sat Sep 21 00:30:42 2019
@@ -560,24 +560,58 @@ INTERCEPTOR(long long, atoll, const char
 }
 #endif  // ASAN_INTERCEPT_ATOLL_AND_STRTOLL
 
-#if ASAN_INTERCEPT___CXA_ATEXIT
+#if ASAN_INTERCEPT___CXA_ATEXIT || ASAN_INTERCEPT_ATEXIT
 static void AtCxaAtexit(void *unused) {
   (void)unused;
   StopInitOrderChecking();
 }
+#endif
 
+#if ASAN_INTERCEPT___CXA_ATEXIT
 INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
             void *dso_handle) {
 #if SANITIZER_MAC
   if (UNLIKELY(!asan_inited)) return REAL(__cxa_atexit)(func, arg, dso_handle);
 #endif
   ENSURE_ASAN_INITED();
+#if CAN_SANITIZE_LEAKS
+  __lsan::ScopedInterceptorDisabler disabler;
+#endif
   int res = REAL(__cxa_atexit)(func, arg, dso_handle);
   REAL(__cxa_atexit)(AtCxaAtexit, nullptr, nullptr);
   return res;
 }
 #endif  // ASAN_INTERCEPT___CXA_ATEXIT
 
+#if ASAN_INTERCEPT_ATEXIT
+INTERCEPTOR(int, atexit, void (*func)()) {
+  ENSURE_ASAN_INITED();
+#if CAN_SANITIZE_LEAKS
+  __lsan::ScopedInterceptorDisabler disabler;
+#endif
+  // Avoid calling real atexit as it is unrechable on at least on Linux.
+  int res = REAL(__cxa_atexit)((void (*)(void *a))func, nullptr, nullptr);
+  REAL(__cxa_atexit)(AtCxaAtexit, nullptr, nullptr);
+  return res;
+}
+#endif
+
+#if ASAN_INTERCEPT_PTHREAD_ATFORK
+extern "C" {
+extern int _pthread_atfork(void (*prepare)(), void (*parent)(),
+                           void (*child)());
+};
+
+INTERCEPTOR(int, pthread_atfork, void (*prepare)(), void (*parent)(),
+            void (*child)()) {
+#if CAN_SANITIZE_LEAKS
+  __lsan::ScopedInterceptorDisabler disabler;
+#endif
+  // REAL(pthread_atfork) cannot be called due to symbol indirections at least on NetBSD
+  return _pthread_atfork(prepare, parent, child);
+}
+#endif
+
 #if ASAN_INTERCEPT_VFORK
 DEFINE_REAL(int, vfork)
 DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(int, vfork)
@@ -660,6 +694,14 @@ void InitializeAsanInterceptors() {
   ASAN_INTERCEPT_FUNC(__cxa_atexit);
 #endif
 
+#if ASAN_INTERCEPT_ATEXIT
+  ASAN_INTERCEPT_FUNC(atexit);
+#endif
+
+#if ASAN_INTERCEPT_PTHREAD_ATFORK
+  ASAN_INTERCEPT_FUNC(pthread_atfork);
+#endif
+
 #if ASAN_INTERCEPT_VFORK
   ASAN_INTERCEPT_FUNC(vfork);
 #endif

Modified: compiler-rt/trunk/lib/asan/asan_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.h?rev=372459&r1=372458&r2=372459&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.h (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.h Sat Sep 21 00:30:42 2019
@@ -99,6 +99,12 @@ void InitializePlatformInterceptors();
 # define ASAN_INTERCEPT___CXA_ATEXIT 0
 #endif
 
+#if SANITIZER_NETBSD
+# define ASAN_INTERCEPT_ATEXIT 1
+#else
+# define ASAN_INTERCEPT_ATEXIT 0
+#endif
+
 #if SANITIZER_LINUX && !SANITIZER_ANDROID
 # define ASAN_INTERCEPT___STRDUP 1
 #else
@@ -112,6 +118,12 @@ void InitializePlatformInterceptors();
 # define ASAN_INTERCEPT_VFORK 0
 #endif
 
+#if SANITIZER_NETBSD
+# define ASAN_INTERCEPT_PTHREAD_ATFORK 1
+#else
+# define ASAN_INTERCEPT_PTHREAD_ATFORK 0
+#endif
+
 DECLARE_REAL(int, memcmp, const void *a1, const void *a2, uptr size)
 DECLARE_REAL(char*, strchr, const char *str, int c)
 DECLARE_REAL(SIZE_T, strlen, const char *s)

Modified: compiler-rt/trunk/lib/lsan/lsan_interceptors.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_interceptors.cpp?rev=372459&r1=372458&r2=372459&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_interceptors.cpp (original)
+++ compiler-rt/trunk/lib/lsan/lsan_interceptors.cpp Sat Sep 21 00:30:42 2019
@@ -345,6 +345,44 @@ INTERCEPTOR(void, thr_exit, tid_t *state
 #define LSAN_MAYBE_INTERCEPT_THR_EXIT
 #endif
 
+#if SANITIZER_INTERCEPT___CXA_ATEXIT
+INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
+            void *dso_handle) {
+  __lsan::ScopedInterceptorDisabler disabler;
+  return REAL(__cxa_atexit)(func, arg, dso_handle);
+}
+#define LSAN_MAYBE_INTERCEPT___CXA_ATEXIT INTERCEPT_FUNCTION(__cxa_atexit)
+#else
+#define LSAN_MAYBE_INTERCEPT___CXA_ATEXIT
+#endif
+
+#if SANITIZER_INTERCEPT_ATEXIT
+INTERCEPTOR(int, atexit, void (*f)()) {
+  __lsan::ScopedInterceptorDisabler disabler;
+  return REAL(__cxa_atexit)((void (*)(void *a))f, 0, 0);
+}
+#define LSAN_MAYBE_INTERCEPT_ATEXIT INTERCEPT_FUNCTION(atexit)
+#else
+#define LSAN_MAYBE_INTERCEPT_ATEXIT
+#endif
+
+#if SANITIZER_INTERCEPT_PTHREAD_ATFORK
+extern "C" {
+extern int _pthread_atfork(void (*prepare)(), void (*parent)(),
+                           void (*child)());
+};
+
+INTERCEPTOR(int, pthread_atfork, void (*prepare)(), void (*parent)(),
+            void (*child)()) {
+  __lsan::ScopedInterceptorDisabler disabler;
+  // REAL(pthread_atfork) cannot be called due to symbol indirections at least on NetBSD
+  return _pthread_atfork(prepare, parent, child);
+}
+#define LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK INTERCEPT_FUNCTION(pthread_atfork)
+#else
+#define LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK
+#endif
+
 struct ThreadParam {
   void *(*callback)(void *arg);
   void *param;
@@ -454,6 +492,10 @@ void InitializeInterceptors() {
   LSAN_MAYBE_INTERCEPT__LWP_EXIT;
   LSAN_MAYBE_INTERCEPT_THR_EXIT;
 
+  LSAN_MAYBE_INTERCEPT___CXA_ATEXIT;
+  LSAN_MAYBE_INTERCEPT_ATEXIT;
+  LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK;
+
 #if !SANITIZER_NETBSD && !SANITIZER_FREEBSD
   if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) {
     Report("LeakSanitizer: failed to create thread key.\n");

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h?rev=372459&r1=372458&r2=372459&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h Sat Sep 21 00:30:42 2019
@@ -567,5 +567,9 @@
 #define SANITIZER_INTERCEPT_SL_INIT (SI_FREEBSD || SI_NETBSD)
 
 #define SANITIZER_INTERCEPT_GETRANDOM SI_LINUX
+#define SANITIZER_INTERCEPT___CXA_ATEXIT SI_NETBSD
+#define SANITIZER_INTERCEPT_ATEXIT SI_NETBSD
+#define SANITIZER_INTERCEPT_PTHREAD_ATFORK SI_NETBSD
+
 
 #endif  // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H




More information about the llvm-commits mailing list