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] Add debug option to "deflake" leaks #112037

Merged

Conversation

vitalybuka
Copy link
Collaborator

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.

@llvmbot
Copy link
Member

llvmbot commented Oct 11, 2024

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

Author: Vitaly Buka (vitalybuka)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/112037.diff

3 Files Affected:

  • (modified) compiler-rt/lib/lsan/lsan_common.cpp (+8-1)
  • (modified) compiler-rt/lib/lsan/lsan_flags.inc (+1)
  • (added) compiler-rt/test/lsan/TestCases/flag_retries.c (+23)
diff --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp
index b584d1e9723fc8..8ed2cfc63cbae9 100644
--- a/compiler-rt/lib/lsan/lsan_common.cpp
+++ b/compiler-rt/lib/lsan/lsan_common.cpp
@@ -779,7 +779,7 @@ static bool PrintResults(LeakReport &report) {
   return unsuppressed_count;
 }
 
-static bool CheckForLeaks() {
+static bool CheckForLeaksOnce() {
   if (&__lsan_is_turned_off && __lsan_is_turned_off()) {
     VReport(1, "LeakSanitizer is disabled\n");
     return false;
@@ -831,6 +831,13 @@ static bool CheckForLeaks() {
   }
 }
 
+static bool CheckForLeaks() {
+  int with_leaks = 0;
+  for (int i = 0; i < flags()->retries; ++i)
+    with_leaks += CheckForLeaksOnce();
+  return with_leaks == flags()->retries;
+}
+
 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..59edc0baa77d85 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, retries, 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_retries.c b/compiler-rt/test/lsan/TestCases/flag_retries.c
new file mode 100644
index 00000000000000..3891a47bb0a566
--- /dev/null
+++ b/compiler-rt/test/lsan/TestCases/flag_retries.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:retries=12 %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK12
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sanitizer/lsan_interface.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);
+}

@vitalybuka vitalybuka requested a review from fmayer October 11, 2024 19:23
Copy link

github-actions bot commented Oct 11, 2024

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

Created using spr 1.3.4
Created using spr 1.3.4
@vitalybuka vitalybuka requested a review from fmayer October 11, 2024 21:39
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-add-debug-option-to-deflake-leaks to main October 11, 2024 23:29
@vitalybuka vitalybuka merged commit e1cff8b into main Oct 11, 2024
7 checks passed
@vitalybuka vitalybuka deleted the users/vitalybuka/spr/lsan-add-debug-option-to-deflake-leaks branch October 11, 2024 23:57
DanielCChen pushed a commit to DanielCChen/llvm-project that referenced this pull request Oct 16, 2024
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.
bricknerb pushed a commit to bricknerb/llvm-project that referenced this pull request Oct 17, 2024
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.
EricWF pushed a commit to efcs/llvm-project that referenced this pull request Oct 22, 2024
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.
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