From b5769dbb86173c1cafb083012ed78acc5bbbd77c Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Tue, 17 Dec 2013 18:01:45 +0000 Subject: [PATCH] [lsan] Introduce print_suppressions flag. Introduce a flag to either always or never print matched suppressions. Previously, matched suppressions were printed unconditionally if there were unsuppressed leaks. Also, verbosity=1 no longer has the semantics of "always print suppressions and summary". llvm-svn: 197510 --- .../lit_tests/TestCases/leak_check_at_exit.cc | 12 ++++--- .../lit_tests/TestCases/print_suppressions.cc | 33 +++++++++++++++++++ compiler-rt/lib/lsan/lsan_common.cc | 9 +++-- compiler-rt/lib/lsan/lsan_common.h | 2 ++ 4 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 compiler-rt/lib/lsan/lit_tests/TestCases/print_suppressions.cc diff --git a/compiler-rt/lib/lsan/lit_tests/TestCases/leak_check_at_exit.cc b/compiler-rt/lib/lsan/lit_tests/TestCases/leak_check_at_exit.cc index 38c1063b6ebb..d921afc8462b 100644 --- a/compiler-rt/lib/lsan/lit_tests/TestCases/leak_check_at_exit.cc +++ b/compiler-rt/lib/lsan/lit_tests/TestCases/leak_check_at_exit.cc @@ -1,15 +1,17 @@ // Test for the leak_check_at_exit flag. +// RUN: LSAN_BASE="use_stacks=0:use_registers=0" // RUN: %clangxx_lsan %s -o %t -// RUN: LSAN_OPTIONS="verbosity=1" %t foo 2>&1 | FileCheck %s --check-prefix=CHECK-do -// RUN: LSAN_OPTIONS="verbosity=1" %t 2>&1 | FileCheck %s --check-prefix=CHECK-do -// RUN: LSAN_OPTIONS="verbosity=1:leak_check_at_exit=0" ASAN_OPTIONS="$ASAN_OPTIONS:leak_check_at_exit=0" %t foo 2>&1 | FileCheck %s --check-prefix=CHECK-do -// RUN: LSAN_OPTIONS="verbosity=1:leak_check_at_exit=0" ASAN_OPTIONS="$ASAN_OPTIONS:leak_check_at_exit=0" %t 2>&1 | FileCheck %s --check-prefix=CHECK-dont +// RUN: LSAN_OPTIONS=$LSAN_BASE not %t foo 2>&1 | FileCheck %s --check-prefix=CHECK-do +// RUN: LSAN_OPTIONS=$LSAN_BASE not %t 2>&1 | FileCheck %s --check-prefix=CHECK-do +// RUN: LSAN_OPTIONS=$LSAN_BASE:"leak_check_at_exit=0" ASAN_OPTIONS="$ASAN_OPTIONS:leak_check_at_exit=0" not %t foo 2>&1 | FileCheck %s --check-prefix=CHECK-do +// RUN: LSAN_OPTIONS=%LSAN_BASE:"leak_check_at_exit=0" ASAN_OPTIONS="$ASAN_OPTIONS:leak_check_at_exit=0" %t 2>&1 | FileCheck %s --check-prefix=CHECK-dont #include +#include #include int main(int argc, char *argv[]) { - printf("printf to break optimization\n"); + fprintf(stderr, "Test alloc: %p.\n", malloc(1337)); if (argc > 1) __lsan_do_leak_check(); return 0; diff --git a/compiler-rt/lib/lsan/lit_tests/TestCases/print_suppressions.cc b/compiler-rt/lib/lsan/lit_tests/TestCases/print_suppressions.cc new file mode 100644 index 000000000000..97e67a016310 --- /dev/null +++ b/compiler-rt/lib/lsan/lit_tests/TestCases/print_suppressions.cc @@ -0,0 +1,33 @@ +// Print matched suppressions only if print_suppressions=1 AND at least one is +// matched. Default is print_suppressions=true. +// RUN: LSAN_BASE="use_registers=0:use_stacks=0" +// RUN: %clangxx_lsan %s -o %t +// RUN: LSAN_OPTIONS=$LSAN_BASE:print_suppressions=0 %t 2>&1 | FileCheck %s --check-prefix=CHECK-dont-print +// RUN: LSAN_OPTIONS=$LSAN_BASE %t 2>&1 | FileCheck %s --check-prefix=CHECK-dont-print +// RUN: LSAN_OPTIONS=$LSAN_BASE:print_suppressions=0 %t foo 2>&1 | FileCheck %s --check-prefix=CHECK-dont-print +// RUN: LSAN_OPTIONS=$LSAN_BASE %t foo 2>&1 | FileCheck %s --check-prefix=CHECK-print + +#include +#include + +#include "sanitizer/lsan_interface.h" + +extern "C" +const char *__lsan_default_suppressions() { + return "leak:*LSanTestLeakingFunc*"; +} + +void LSanTestLeakingFunc() { + void *p = malloc(666); + fprintf(stderr, "Test alloc: %p.\n", p); +} + +int main(int argc, char **argv) { + printf("print for nonempty output\n"); + if (argc > 1) + LSanTestLeakingFunc(); + return 0; +} +// CHECK-print: Suppressions used: +// CHECK-print: 1 666 *LSanTestLeakingFunc* +// CHECK-dont-print-NOT: Suppressions used: diff --git a/compiler-rt/lib/lsan/lsan_common.cc b/compiler-rt/lib/lsan/lsan_common.cc index 0ff492fc930a..7cc6b1573a11 100644 --- a/compiler-rt/lib/lsan/lsan_common.cc +++ b/compiler-rt/lib/lsan/lsan_common.cc @@ -43,6 +43,7 @@ static void InitializeFlags() { f->resolution = 0; f->max_leaks = 0; f->exitcode = 23; + f->print_suppressions = true; f->suppressions=""; f->use_registers = true; f->use_globals = true; @@ -73,6 +74,7 @@ static void InitializeFlags() { ParseFlag(options, &f->log_pointers, "log_pointers"); ParseFlag(options, &f->log_threads, "log_threads"); ParseFlag(options, &f->exitcode, "exitcode"); + ParseFlag(options, &f->print_suppressions, "print_suppressions"); ParseFlag(options, &f->suppressions, "suppressions"); } } @@ -467,12 +469,13 @@ void DoLeakCheck() { Printf("%s", d.End()); param.leak_report.PrintLargest(flags()->max_leaks); } - if (have_unsuppressed || (flags()->verbosity >= 1)) { + if (flags()->print_suppressions) PrintMatchedSuppressions(); + if (have_unsuppressed) { param.leak_report.PrintSummary(); + if (flags()->exitcode) + internal__exit(flags()->exitcode); } - if (have_unsuppressed && flags()->exitcode) - internal__exit(flags()->exitcode); } static Suppression *GetSuppressionForAddr(uptr addr) { diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h index 452824e12f19..85bb5631cdcc 100644 --- a/compiler-rt/lib/lsan/lsan_common.h +++ b/compiler-rt/lib/lsan/lsan_common.h @@ -51,6 +51,8 @@ struct Flags { int max_leaks; // If nonzero kill the process with this exit code upon finding leaks. int exitcode; + // Print matched suppressions after leak checking. + bool print_suppressions; // Suppressions file name. const char* suppressions;