Index: lib/lsan/lsan_common.cc =================================================================== --- lib/lsan/lsan_common.cc +++ lib/lsan/lsan_common.cc @@ -449,6 +449,8 @@ Report( "HINT: For debugging, try setting environment variable " "LSAN_OPTIONS=verbosity=1:log_threads=1\n"); + Report( + "HINT: LeakSanitizer does not work under ptrace (strace, gdb, etc)\n"); Die(); } param.leak_report.ApplySuppressions(); Index: lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc +++ lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc @@ -190,6 +190,7 @@ bool ThreadSuspender::SuspendAllThreads() { ThreadLister thread_lister(pid_); bool added_threads; + bool first_iteration = true; do { // Run through the directory entries once. added_threads = false; @@ -199,12 +200,13 @@ added_threads = true; tid = thread_lister.GetNextTID(); } - if (thread_lister.error()) { + if (thread_lister.error() || (first_iteration && !added_threads)) { // Detach threads and fail. ResumeAllThreads(); return false; } thread_lister.Reset(); + first_iteration = false; } while (added_threads); return true; } Index: test/lsan/TestCases/strace_test.cc =================================================================== --- /dev/null +++ test/lsan/TestCases/strace_test.cc @@ -0,0 +1,14 @@ +// Test that lsan reports a proper error when running under strace. +// RUN: %clangxx_lsan %s -o %t +// RUN: not strace -o /dev/null %run %t 2>&1 | FileCheck %s + +#include +#include + +static volatile void *sink; + +int main() { + sink = malloc(42); +} +// CHECK: LeakSanitizer has encountered a fatal error +// CHECK: HINT: LeakSanitizer does not work under ptrace (strace, gdb, etc)