[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