Skip to content

Commit

Permalink
[lsan] Add debug option to "deflake" leaks (#112037)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
vitalybuka authored Oct 11, 2024
1 parent 9025202 commit e1cff8b
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 1 deletion.
8 changes: 7 additions & 1 deletion compiler-rt/lib/lsan/lsan_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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; }

Expand Down
1 change: 1 addition & 0 deletions compiler-rt/lib/lsan/lsan_flags.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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 - "
Expand Down
23 changes: 23 additions & 0 deletions compiler-rt/test/lsan/TestCases/flag_tries.c
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit e1cff8b

Please sign in to comment.