[compiler-rt] r186581 - [lsan] Add __lsan_do_leak_check() to the public interface.

Sergey Matveev earthdok at google.com
Thu Jul 18 07:06:07 PDT 2013


Author: smatveev
Date: Thu Jul 18 09:06:07 2013
New Revision: 186581

URL: http://llvm.org/viewvc/llvm-project?rev=186581&view=rev
Log:
[lsan] Add __lsan_do_leak_check() to the public interface.

Let users override the normal behavior to run leak checking earlier in
the process. Also fix a couple nits here and there.

Added:
    compiler-rt/trunk/lib/lsan/lit_tests/TestCases/do_leak_check_override.cc
Modified:
    compiler-rt/trunk/include/sanitizer/lsan_interface.h
    compiler-rt/trunk/lib/lsan/lsan_common.cc

Modified: compiler-rt/trunk/include/sanitizer/lsan_interface.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/lsan_interface.h?rev=186581&r1=186580&r2=186581&view=diff
==============================================================================
--- compiler-rt/trunk/include/sanitizer/lsan_interface.h (original)
+++ compiler-rt/trunk/include/sanitizer/lsan_interface.h Thu Jul 18 09:06:07 2013
@@ -20,15 +20,23 @@
 extern "C" {
 #endif
   // Allocations made between calls to __lsan_disable() and __lsan_enable() will
-  // be treated as non-leaks. Disable/enable pairs can be nested.
+  // be treated as non-leaks. Disable/enable pairs may be nested.
   void __lsan_disable();
   void __lsan_enable();
   // The heap object into which p points will be treated as a non-leak.
   void __lsan_ignore_object(const void *p);
   // The user may optionally provide this function to disallow leak checking
-  // for the program it is linked into. Note: this function may be called late,
-  // after all the global destructors.
+  // for the program it is linked into (if the return value is non-zero). This
+  // function must be defined as returning a constant value; any behavior beyond
+  // that is unsupported.
   int __lsan_is_turned_off();
+  // Calling this function makes LSan enter the leak checking phase immediately.
+  // Use this if normal end-of-process leak checking happens too late (e.g. if
+  // you have intentional memory leaks in your shutdown code). Calling this
+  // function overrides end-of-process leak checking; it must be called at
+  // most once per process. This function will terminate the process if there
+  // are memory leaks and the exit_code flag is non-zero. 
+  void __lsan_do_leak_check();
 #ifdef __cplusplus
 }  // extern "C"
 

Added: compiler-rt/trunk/lib/lsan/lit_tests/TestCases/do_leak_check_override.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lit_tests/TestCases/do_leak_check_override.cc?rev=186581&view=auto
==============================================================================
--- compiler-rt/trunk/lib/lsan/lit_tests/TestCases/do_leak_check_override.cc (added)
+++ compiler-rt/trunk/lib/lsan/lit_tests/TestCases/do_leak_check_override.cc Thu Jul 18 09:06:07 2013
@@ -0,0 +1,36 @@
+// Test for __lsan_do_leak_check(). We test it by making the leak check run
+// before global destructors, which also tests compatibility with HeapChecker's
+// "normal" mode (LSan runs in "strict" mode by default).
+// RUN: LSAN_BASE="use_stacks=0:use_registers=0"
+// RUN: %clangxx_lsan %s -o %t
+// RUN: LSAN_OPTIONS=$LSAN_BASE %t 2>&1 | FileCheck --check-prefix=CHECK-strict %s
+// RUN: LSAN_OPTIONS=$LSAN_BASE %t foo 2>&1 | FileCheck --check-prefix=CHECK-normal %s
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sanitizer/lsan_interface.h>
+
+struct LeakyGlobal {
+  LeakyGlobal() {
+    p = malloc(1337);
+  }
+  ~LeakyGlobal() {
+    p = 0;
+  }
+  void *p;
+};
+
+LeakyGlobal leaky_global;
+
+int main(int argc, char *argv[]) {
+  // Register leak check to run before global destructors.
+  if (argc > 1)
+    atexit(&__lsan_do_leak_check);
+  void *p = malloc(666);
+  printf("Test alloc: %p\n", p);
+  printf("Test alloc in leaky global: %p\n", leaky_global.p);
+  return 0;
+}
+
+// CHECK-strict: SUMMARY: LeakSanitizer: 2003 byte(s) leaked in 2 allocation(s)
+// CHECK-normal: SUMMARY: LeakSanitizer: 666 byte(s) leaked in 1 allocation(s)

Modified: compiler-rt/trunk/lib/lsan/lsan_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_common.cc?rev=186581&r1=186580&r2=186581&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_common.cc (original)
+++ compiler-rt/trunk/lib/lsan/lsan_common.cc Thu Jul 18 09:06:07 2013
@@ -125,7 +125,7 @@ void ScanRangeForPointers(uptr begin, up
   if (pp % alignment)
     pp = pp + alignment - pp % alignment;
   for (; pp + sizeof(void *) <= end; pp += alignment) {  // NOLINT
-    void *p = *reinterpret_cast<void**>(pp);
+    void *p = *reinterpret_cast<void **>(pp);
     if (!CanBeAHeapPointer(reinterpret_cast<uptr>(p))) continue;
     uptr chunk = PointsIntoChunk(p);
     if (!chunk) continue;
@@ -353,7 +353,7 @@ void DoLeakCheck() {
   EnsureMainThreadIDIsCorrect();
   BlockingMutexLock l(&global_mutex);
   static bool already_done;
-  CHECK(!already_done);
+  if (already_done) return;
   already_done = true;
   if (&__lsan_is_turned_off && __lsan_is_turned_off())
     return;
@@ -544,6 +544,13 @@ void __lsan_enable() {
 #endif
 }
 
+SANITIZER_INTERFACE_ATTRIBUTE
+void __lsan_do_leak_check() {
+#if CAN_SANITIZE_LEAKS
+  __lsan::DoLeakCheck();
+#endif
+}
+
 #if !SANITIZER_SUPPORTS_WEAK_HOOKS
 SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE
 int __lsan_is_turned_off() {





More information about the llvm-commits mailing list