[compiler-rt] e1cff8b - [lsan] Add debug option to "deflake" leaks (#112037)

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 11 16:57:23 PDT 2024


Author: Vitaly Buka
Date: 2024-10-11T16:57:19-07:00
New Revision: e1cff8bf816b41b4fb1333533ee1225ae2148a0d

URL: https://github.com/llvm/llvm-project/commit/e1cff8bf816b41b4fb1333533ee1225ae2148a0d
DIFF: https://github.com/llvm/llvm-project/commit/e1cff8bf816b41b4fb1333533ee1225ae2148a0d.diff

LOG: [lsan] Add debug option to "deflake" leaks (#112037)

There are hard to debug leaks which look like
false.

In general, repeating leak checking should not
affect set of leaks significantly, especial
`at_exit` leak checking.

But if we see significant discrepancy, it may give
us a clue for investigation.

Added: 
    compiler-rt/test/lsan/TestCases/flag_tries.c

Modified: 
    compiler-rt/lib/lsan/lsan_common.cpp
    compiler-rt/lib/lsan/lsan_flags.inc

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp
index 6776598651ae9b..52d0a8c3c96ae3 100644
--- a/compiler-rt/lib/lsan/lsan_common.cpp
+++ b/compiler-rt/lib/lsan/lsan_common.cpp
@@ -778,7 +778,7 @@ static bool PrintResults(LeakReport &report) {
   return false;
 }
 
-static bool CheckForLeaks() {
+static bool CheckForLeaksOnce() {
   if (&__lsan_is_turned_off && __lsan_is_turned_off()) {
     VReport(1, "LeakSanitizer is disabled\n");
     return false;
@@ -830,6 +830,12 @@ static bool CheckForLeaks() {
   }
 }
 
+static bool CheckForLeaks() {
+  int leaking_tries = 0;
+  for (int i = 0; i < flags()->tries; ++i) leaking_tries += CheckForLeaksOnce();
+  return leaking_tries == flags()->tries;
+}
+
 static bool has_reported_leaks = false;
 bool HasReportedLeaks() { return has_reported_leaks; }
 

diff  --git a/compiler-rt/lib/lsan/lsan_flags.inc b/compiler-rt/lib/lsan/lsan_flags.inc
index b7f28223b8189b..c97b021ba5c02f 100644
--- a/compiler-rt/lib/lsan/lsan_flags.inc
+++ b/compiler-rt/lib/lsan/lsan_flags.inc
@@ -43,6 +43,7 @@ LSAN_FLAG(bool, use_poisoned, false,
           "Consider pointers found in poisoned memory to be valid.")
 LSAN_FLAG(bool, log_pointers, false, "Debug logging")
 LSAN_FLAG(bool, log_threads, false, "Debug logging")
+LSAN_FLAG(int, tries, 1, "Debug option to repeat leak checking multiple times")
 LSAN_FLAG(const char *, suppressions, "", "Suppressions file name.")
 LSAN_FLAG(int, thread_suspend_fail, 1,
           "Behaviour if thread suspendion all thread (0 - "

diff  --git a/compiler-rt/test/lsan/TestCases/flag_tries.c b/compiler-rt/test/lsan/TestCases/flag_tries.c
new file mode 100644
index 00000000000000..d6af766d5ef282
--- /dev/null
+++ b/compiler-rt/test/lsan/TestCases/flag_tries.c
@@ -0,0 +1,23 @@
+// Test retries option of lsan.
+// RUN: %clang_lsan %s -o %t
+// RUN: %env_lsan_opts=use_stacks=0:use_registers=0:symbolize=0 %run %t foo 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK1
+// RUN: %env_lsan_opts=use_stacks=0:use_registers=0:symbolize=0:tries=12 %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK12
+
+#include <assert.h>
+#include <sanitizer/lsan_interface.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+void *p;
+
+int main(int argc, char *argv[]) {
+  fprintf(stderr, "Test alloc: %p.\n", malloc(1337));
+  // CHECK: Test alloc:
+
+  assert(__lsan_do_recoverable_leak_check() == 1);
+  // CHECK1-COUNT-1: SUMMARY: {{.*}}Sanitizer: 1337 byte
+  // CHECK12-COUNT-12: SUMMARY: {{.*}}Sanitizer: 1337 byte
+
+  _exit(0);
+}


        


More information about the llvm-commits mailing list