Skip to content

Commit fa81868

Browse files
authored
[lsan] Log thread history (#111949)
Only with high verbosity and leak reports, or thread logging requested.
1 parent f1367a4 commit fa81868

File tree

6 files changed

+59
-5
lines changed

6 files changed

+59
-5
lines changed

compiler-rt/lib/asan/asan_thread.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "sanitizer_common/sanitizer_common.h"
2222
#include "sanitizer_common/sanitizer_placement_new.h"
2323
#include "sanitizer_common/sanitizer_stackdepot.h"
24+
#include "sanitizer_common/sanitizer_thread_history.h"
2425
#include "sanitizer_common/sanitizer_tls_get_addr.h"
2526

2627
namespace __asan {
@@ -555,6 +556,12 @@ void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {
555556
threads);
556557
}
557558

559+
void PrintThreads() {
560+
InternalScopedString out;
561+
PrintThreadHistory(__asan::asanThreadRegistry(), out);
562+
Report("%s\n", out.data());
563+
}
564+
558565
} // namespace __lsan
559566

560567
// ---------------------- Interface ---------------- {{{1

compiler-rt/lib/hwasan/hwasan_thread.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,11 @@ void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs) {
218218
__hwasan::hwasanThreadArgRetval().GetAllPtrsLocked(ptrs);
219219
}
220220

221-
void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {}
221+
void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {
222+
// TODO: implement.
223+
}
224+
void PrintThreads() {
225+
// TODO: implement.
226+
}
222227

223228
} // namespace __lsan

compiler-rt/lib/lsan/lsan_common.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -771,11 +771,12 @@ static bool PrintResults(LeakReport &report) {
771771
}
772772
if (common_flags()->print_suppressions)
773773
GetSuppressionContext()->PrintMatchedSuppressions();
774-
if (unsuppressed_count > 0) {
774+
if (unsuppressed_count)
775775
report.PrintSummary();
776-
return true;
777-
}
778-
return false;
776+
if ((unsuppressed_count && common_flags()->verbosity >= 2) ||
777+
flags()->log_threads)
778+
PrintThreads();
779+
return unsuppressed_count;
779780
}
780781

781782
static bool CheckForLeaksOnce() {

compiler-rt/lib/lsan/lsan_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ void GetThreadExtraStackRangesLocked(tid_t os_id,
111111
InternalMmapVector<Range> *ranges);
112112
void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs);
113113
void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads);
114+
void PrintThreads();
114115

115116
//// --------------------------------------------------------------------------
116117
//// Allocator prototypes.

compiler-rt/lib/lsan/lsan_thread.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "lsan_common.h"
1919
#include "sanitizer_common/sanitizer_common.h"
2020
#include "sanitizer_common/sanitizer_placement_new.h"
21+
#include "sanitizer_common/sanitizer_thread_history.h"
2122
#include "sanitizer_common/sanitizer_thread_registry.h"
2223
#include "sanitizer_common/sanitizer_tls_get_addr.h"
2324

@@ -109,6 +110,12 @@ void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {
109110
threads);
110111
}
111112

113+
void PrintThreads() {
114+
InternalScopedString out;
115+
PrintThreadHistory(*thread_registry, out);
116+
Report("%s\n", out.data());
117+
}
118+
112119
void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs) {
113120
GetThreadArgRetval().GetAllPtrsLocked(ptrs);
114121
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// RUN: %clang_lsan %s -o %t && %env_lsan_opts=log_threads=1 %run %t 2>&1 | FileCheck %s
2+
3+
// XFAIL: hwasan
4+
5+
#include <assert.h>
6+
#include <pthread.h>
7+
#include <sanitizer/lsan_interface.h>
8+
#include <stdio.h>
9+
#include <stdlib.h>
10+
#include <unistd.h>
11+
12+
pthread_barrier_t bar;
13+
14+
void *threadfn(void *arg) {
15+
pthread_barrier_wait(&bar);
16+
sleep(10000);
17+
return 0;
18+
}
19+
20+
int main(int argc, char *argv[]) {
21+
pthread_t thread_id;
22+
pthread_barrier_init(&bar, 0, 3);
23+
24+
pthread_create(&thread_id, 0, threadfn, 0);
25+
pthread_create(&thread_id, 0, threadfn, 0);
26+
27+
pthread_barrier_wait(&bar);
28+
return 0;
29+
}
30+
31+
// CHECK: Thread T0/{{[0-9]+}} was created by T-1
32+
// CHECK: Thread T1/{{[0-9]+}} was created by T0/
33+
// CHECK: Thread T2/{{[0-9]+}} was created by T0/

0 commit comments

Comments
 (0)