diff options
author | Sergey Matveev <earthdok@google.com> | 2013-06-19 14:04:11 +0000 |
---|---|---|
committer | Sergey Matveev <earthdok@google.com> | 2013-06-19 14:04:11 +0000 |
commit | dac35c24c0f079ba9d764869e04797bc869dcbcf (patch) | |
tree | 53caf0dd02ac05c06f8da1373b8e9883e027eabe | |
parent | f86ae72e6df71952530bc3f61959e43facd8b6bf (diff) | |
download | bcm5719-llvm-dac35c24c0f079ba9d764869e04797bc869dcbcf.tar.gz bcm5719-llvm-dac35c24c0f079ba9d764869e04797bc869dcbcf.zip |
[lsan] Move symbolization and reporting out of StopTheWorld callback.
llvm-svn: 184303
14 files changed, 47 insertions, 40 deletions
diff --git a/compiler-rt/lib/lsan/lit_tests/TestCases/large_allocation_leak.cc b/compiler-rt/lib/lsan/lit_tests/TestCases/large_allocation_leak.cc index 1379e6a5648..2c36721364f 100644 --- a/compiler-rt/lib/lsan/lit_tests/TestCases/large_allocation_leak.cc +++ b/compiler-rt/lib/lsan/lit_tests/TestCases/large_allocation_leak.cc @@ -13,6 +13,6 @@ int main() { return 0; } // CHECK: Test alloc: [[ADDR:.*]]. -// CHECK: LeakSanitizer: detected memory leaks // CHECK: Directly leaked 33554432 byte object at [[ADDR]] +// CHECK: LeakSanitizer: detected memory leaks // CHECK: SUMMARY: LeakSanitizer: diff --git a/compiler-rt/lib/lsan/lit_tests/TestCases/stale_stack_leak.cc b/compiler-rt/lib/lsan/lit_tests/TestCases/stale_stack_leak.cc index 6088e2ee26b..5129a7e7fc1 100644 --- a/compiler-rt/lib/lsan/lit_tests/TestCases/stale_stack_leak.cc +++ b/compiler-rt/lib/lsan/lit_tests/TestCases/stale_stack_leak.cc @@ -36,7 +36,7 @@ void ConfirmPointerHasSurvived() { } // CHECK: Test alloc: [[ADDR:.*]]. // CHECK-sanity: Test alloc: [[ADDR:.*]]. -// CHECK: LeakSanitizer: detected memory leaks // CHECK: Directly leaked 1337 byte object at [[ADDR]] +// CHECK: LeakSanitizer: detected memory leaks // CHECK: SUMMARY: LeakSanitizer: // CHECK-sanity: Value after LSan: [[ADDR]]. diff --git a/compiler-rt/lib/lsan/lit_tests/TestCases/use_globals_initialized.cc b/compiler-rt/lib/lsan/lit_tests/TestCases/use_globals_initialized.cc index 67baa29b302..a53cdff78ac 100644 --- a/compiler-rt/lib/lsan/lit_tests/TestCases/use_globals_initialized.cc +++ b/compiler-rt/lib/lsan/lit_tests/TestCases/use_globals_initialized.cc @@ -16,6 +16,6 @@ int main() { return 0; } // CHECK: Test alloc: [[ADDR:.*]]. -// CHECK: LeakSanitizer: detected memory leaks // CHECK: Directly leaked 1337 byte object at [[ADDR]] +// CHECK: LeakSanitizer: detected memory leaks // CHECK: SUMMARY: LeakSanitizer: diff --git a/compiler-rt/lib/lsan/lit_tests/TestCases/use_globals_uninitialized.cc b/compiler-rt/lib/lsan/lit_tests/TestCases/use_globals_uninitialized.cc index 8ef30280c3b..d6f691fe5ad 100644 --- a/compiler-rt/lib/lsan/lit_tests/TestCases/use_globals_uninitialized.cc +++ b/compiler-rt/lib/lsan/lit_tests/TestCases/use_globals_uninitialized.cc @@ -16,6 +16,6 @@ int main() { return 0; } // CHECK: Test alloc: [[ADDR:.*]]. -// CHECK: LeakSanitizer: detected memory leaks // CHECK: Directly leaked 1337 byte object at [[ADDR]] +// CHECK: LeakSanitizer: detected memory leaks // CHECK: SUMMARY: LeakSanitizer: diff --git a/compiler-rt/lib/lsan/lit_tests/TestCases/use_registers.cc b/compiler-rt/lib/lsan/lit_tests/TestCases/use_registers.cc index 71d7c9b5fae..ed37042f1f4 100644 --- a/compiler-rt/lib/lsan/lit_tests/TestCases/use_registers.cc +++ b/compiler-rt/lib/lsan/lit_tests/TestCases/use_registers.cc @@ -46,6 +46,6 @@ int main() { return 0; } // CHECK: Test alloc: [[ADDR:.*]]. -// CHECK: LeakSanitizer: detected memory leaks // CHECK: Directly leaked 1337 byte object at [[ADDR]] +// CHECK: LeakSanitizer: detected memory leaks // CHECK: SUMMARY: LeakSanitizer: diff --git a/compiler-rt/lib/lsan/lit_tests/TestCases/use_stacks.cc b/compiler-rt/lib/lsan/lit_tests/TestCases/use_stacks.cc index 86eef205161..d09518647fd 100644 --- a/compiler-rt/lib/lsan/lit_tests/TestCases/use_stacks.cc +++ b/compiler-rt/lib/lsan/lit_tests/TestCases/use_stacks.cc @@ -15,6 +15,6 @@ int main() { exit(0); } // CHECK: Test alloc: [[ADDR:.*]]. -// CHECK: LeakSanitizer: detected memory leaks // CHECK: Directly leaked 1337 byte object at [[ADDR]] +// CHECK: LeakSanitizer: detected memory leaks // CHECK: SUMMARY: LeakSanitizer: diff --git a/compiler-rt/lib/lsan/lit_tests/TestCases/use_stacks_threaded.cc b/compiler-rt/lib/lsan/lit_tests/TestCases/use_stacks_threaded.cc index 292b4bbf57a..479e4f7f549 100644 --- a/compiler-rt/lib/lsan/lit_tests/TestCases/use_stacks_threaded.cc +++ b/compiler-rt/lib/lsan/lit_tests/TestCases/use_stacks_threaded.cc @@ -31,6 +31,6 @@ int main() { return 0; } // CHECK: Test alloc: [[ADDR:.*]]. -// CHECK: LeakSanitizer: detected memory leaks // CHECK: Directly leaked 1337 byte object at [[ADDR]] +// CHECK: LeakSanitizer: detected memory leaks // CHECK: SUMMARY: LeakSanitizer: diff --git a/compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_dynamic.cc b/compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_dynamic.cc index 5659a2db743..944b7b879c1 100644 --- a/compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_dynamic.cc +++ b/compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_dynamic.cc @@ -28,6 +28,6 @@ int main(int argc, char *argv[]) { return 0; } // CHECK: Test alloc: [[ADDR:.*]]. -// CHECK: LeakSanitizer: detected memory leaks // CHECK: leaked 1337 byte object at [[ADDR]] +// CHECK: LeakSanitizer: detected memory leaks // CHECK: SUMMARY: LeakSanitizer: diff --git a/compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_pthread_specific_dynamic.cc b/compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_pthread_specific_dynamic.cc index 1a6b10c883b..8457ff95c85 100644 --- a/compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_pthread_specific_dynamic.cc +++ b/compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_pthread_specific_dynamic.cc @@ -32,6 +32,6 @@ int main() { return 0; } // CHECK: Test alloc: [[ADDR:.*]]. -// CHECK: LeakSanitizer: detected memory leaks // CHECK: leaked 1337 byte object at [[ADDR]] +// CHECK: LeakSanitizer: detected memory leaks // CHECK: SUMMARY: LeakSanitizer: diff --git a/compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_pthread_specific_static.cc b/compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_pthread_specific_static.cc index 2322a0d5a4c..bd5a296086c 100644 --- a/compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_pthread_specific_static.cc +++ b/compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_pthread_specific_static.cc @@ -26,6 +26,6 @@ int main() { return 0; } // CHECK: Test alloc: [[ADDR:.*]]. -// CHECK: LeakSanitizer: detected memory leaks // CHECK: Directly leaked 1337 byte object at [[ADDR]] +// CHECK: LeakSanitizer: detected memory leaks // CHECK: SUMMARY: LeakSanitizer: diff --git a/compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_static.cc b/compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_static.cc index 2dc6929338a..3ef596938cd 100644 --- a/compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_static.cc +++ b/compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_static.cc @@ -16,6 +16,6 @@ int main() { return 0; } // CHECK: Test alloc: [[ADDR:.*]]. -// CHECK: LeakSanitizer: detected memory leaks // CHECK: Directly leaked 1337 byte object at [[ADDR]] +// CHECK: LeakSanitizer: detected memory leaks // CHECK: SUMMARY: LeakSanitizer: diff --git a/compiler-rt/lib/lsan/lit_tests/TestCases/use_unaligned.cc b/compiler-rt/lib/lsan/lit_tests/TestCases/use_unaligned.cc index 738f737f9cd..890d2a8a324 100644 --- a/compiler-rt/lib/lsan/lit_tests/TestCases/use_unaligned.cc +++ b/compiler-rt/lib/lsan/lit_tests/TestCases/use_unaligned.cc @@ -18,6 +18,6 @@ int main() { return 0; } // CHECK: Test alloc: [[ADDR:.*]]. -// CHECK: LeakSanitizer: detected memory leaks // CHECK: Directly leaked 1337 byte object at [[ADDR]] +// CHECK: LeakSanitizer: detected memory leaks // CHECK: SUMMARY: LeakSanitizer: diff --git a/compiler-rt/lib/lsan/lsan_common.cc b/compiler-rt/lib/lsan/lsan_common.cc index e11d304f3d0..be58f5b4dd3 100644 --- a/compiler-rt/lib/lsan/lsan_common.cc +++ b/compiler-rt/lib/lsan/lsan_common.cc @@ -275,45 +275,34 @@ void PrintLeakedCb::operator()(void *p) const { LsanMetadata m(p); if (!m.allocated()) return; if (m.tag() == kDirectlyLeaked || m.tag() == kIndirectlyLeaked) { - Printf("%s leaked %llu byte object at %p\n", + Printf("%s leaked %llu byte object at %p.\n", m.tag() == kDirectlyLeaked ? "Directly" : "Indirectly", m.requested_size(), p); } } static void PrintLeaked() { + Printf("\n"); Printf("Reporting individual objects:\n"); - Printf("============================\n"); ForEachChunk(PrintLeakedCb()); - Printf("\n"); } -enum LeakCheckResult { - kFatalError, - kLeaksFound, - kNoLeaks +struct DoLeakCheckParam { + bool success; + LeakReport leak_report; }; static void DoLeakCheckCallback(const SuspendedThreadsList &suspended_threads, void *arg) { - LeakCheckResult *result = reinterpret_cast<LeakCheckResult *>(arg); - CHECK_EQ(*result, kFatalError); + DoLeakCheckParam *param = reinterpret_cast<DoLeakCheckParam *>(arg); + CHECK(param); + CHECK(!param->success); + CHECK(param->leak_report.IsEmpty()); ClassifyAllChunks(suspended_threads); - LeakReport leak_report; - CollectLeaks(&leak_report); - if (leak_report.IsEmpty()) { - *result = kNoLeaks; - return; - } - Printf("\n"); - Printf("=================================================================\n"); - Report("ERROR: LeakSanitizer: detected memory leaks\n"); - leak_report.PrintLargest(flags()->max_leaks); - if (flags()->report_objects) + CollectLeaks(¶m->leak_report); + if (!param->leak_report.IsEmpty() && flags()->report_objects) PrintLeaked(); - leak_report.PrintSummary(); - Printf("\n"); - *result = kLeaksFound; + param->success = true; } void DoLeakCheck() { @@ -321,16 +310,25 @@ void DoLeakCheck() { static bool already_done; CHECK(!already_done); already_done = true; - LeakCheckResult result = kFatalError; + + DoLeakCheckParam param; + param.success = false; LockThreadRegistry(); LockAllocator(); - StopTheWorld(DoLeakCheckCallback, &result); + StopTheWorld(DoLeakCheckCallback, ¶m); UnlockAllocator(); UnlockThreadRegistry(); - if (result == kFatalError) { + + if (!param.success) { Report("LeakSanitizer has encountered a fatal error.\n"); Die(); - } else if (result == kLeaksFound) { + } + if (!param.leak_report.IsEmpty()) { + Printf("\n=================================================================" + "\n"); + Report("ERROR: LeakSanitizer: detected memory leaks\n"); + param.leak_report.PrintLargest(flags()->max_leaks); + param.leak_report.PrintSummary(); if (flags()->exitcode) internal__exit(flags()->exitcode); } @@ -396,7 +394,7 @@ void LeakReport::PrintSummary() { bytes += leaks_[i].total_size; allocations += leaks_[i].hit_count; } - Printf("SUMMARY: LeakSanitizer: %llu byte(s) leaked in %llu allocation(s).\n", + Printf("SUMMARY: LeakSanitizer: %llu byte(s) leaked in %llu allocation(s).\n\n", bytes, allocations); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc index da087348c90..f037069a033 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc @@ -278,11 +278,20 @@ class ScopedStackSpaceWithGuard { uptr guard_start_; }; +static void WipeStack() { + char arr[256]; + internal_memset(arr, 0, sizeof(arr)); +} + static sigset_t blocked_sigset; static sigset_t old_sigset; static struct sigaction old_sigactions[ARRAY_SIZE(kUnblockedSignals)]; void StopTheWorld(StopTheWorldCallback callback, void *argument) { + // Glibc's sigaction() has a side-effect where it copies garbage stack values + // into oldact, which can cause false negatives in LSan. As a quick workaround + // we zero some stack space here. + WipeStack(); // Block all signals that can be blocked safely, and install default handlers // for the remaining signals. // We cannot allow user-defined handlers to run while the ThreadSuspender |