summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Matveev <earthdok@google.com>2013-06-19 14:04:11 +0000
committerSergey Matveev <earthdok@google.com>2013-06-19 14:04:11 +0000
commitdac35c24c0f079ba9d764869e04797bc869dcbcf (patch)
tree53caf0dd02ac05c06f8da1373b8e9883e027eabe
parentf86ae72e6df71952530bc3f61959e43facd8b6bf (diff)
downloadbcm5719-llvm-dac35c24c0f079ba9d764869e04797bc869dcbcf.tar.gz
bcm5719-llvm-dac35c24c0f079ba9d764869e04797bc869dcbcf.zip
[lsan] Move symbolization and reporting out of StopTheWorld callback.
llvm-svn: 184303
-rw-r--r--compiler-rt/lib/lsan/lit_tests/TestCases/large_allocation_leak.cc2
-rw-r--r--compiler-rt/lib/lsan/lit_tests/TestCases/stale_stack_leak.cc2
-rw-r--r--compiler-rt/lib/lsan/lit_tests/TestCases/use_globals_initialized.cc2
-rw-r--r--compiler-rt/lib/lsan/lit_tests/TestCases/use_globals_uninitialized.cc2
-rw-r--r--compiler-rt/lib/lsan/lit_tests/TestCases/use_registers.cc2
-rw-r--r--compiler-rt/lib/lsan/lit_tests/TestCases/use_stacks.cc2
-rw-r--r--compiler-rt/lib/lsan/lit_tests/TestCases/use_stacks_threaded.cc2
-rw-r--r--compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_dynamic.cc2
-rw-r--r--compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_pthread_specific_dynamic.cc2
-rw-r--r--compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_pthread_specific_static.cc2
-rw-r--r--compiler-rt/lib/lsan/lit_tests/TestCases/use_tls_static.cc2
-rw-r--r--compiler-rt/lib/lsan/lit_tests/TestCases/use_unaligned.cc2
-rw-r--r--compiler-rt/lib/lsan/lsan_common.cc54
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc9
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(&param->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, &param);
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
OpenPOWER on IntegriCloud