Skip to content

Commit

Permalink
[lsan] Log thread history (#111949)
Browse files Browse the repository at this point in the history
Only with high verbosity and leak reports, or thread logging requested.
  • Loading branch information
vitalybuka authored Oct 12, 2024
1 parent f1367a4 commit fa81868
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 5 deletions.
7 changes: 7 additions & 0 deletions compiler-rt/lib/asan/asan_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_placement_new.h"
#include "sanitizer_common/sanitizer_stackdepot.h"
#include "sanitizer_common/sanitizer_thread_history.h"
#include "sanitizer_common/sanitizer_tls_get_addr.h"

namespace __asan {
Expand Down Expand Up @@ -555,6 +556,12 @@ void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {
threads);
}

void PrintThreads() {
InternalScopedString out;
PrintThreadHistory(__asan::asanThreadRegistry(), out);
Report("%s\n", out.data());
}

} // namespace __lsan

// ---------------------- Interface ---------------- {{{1
Expand Down
7 changes: 6 additions & 1 deletion compiler-rt/lib/hwasan/hwasan_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,11 @@ void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs) {
__hwasan::hwasanThreadArgRetval().GetAllPtrsLocked(ptrs);
}

void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {}
void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {
// TODO: implement.
}
void PrintThreads() {
// TODO: implement.
}

} // namespace __lsan
9 changes: 5 additions & 4 deletions compiler-rt/lib/lsan/lsan_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -771,11 +771,12 @@ static bool PrintResults(LeakReport &report) {
}
if (common_flags()->print_suppressions)
GetSuppressionContext()->PrintMatchedSuppressions();
if (unsuppressed_count > 0) {
if (unsuppressed_count)
report.PrintSummary();
return true;
}
return false;
if ((unsuppressed_count && common_flags()->verbosity >= 2) ||
flags()->log_threads)
PrintThreads();
return unsuppressed_count;
}

static bool CheckForLeaksOnce() {
Expand Down
1 change: 1 addition & 0 deletions compiler-rt/lib/lsan/lsan_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ void GetThreadExtraStackRangesLocked(tid_t os_id,
InternalMmapVector<Range> *ranges);
void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs);
void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads);
void PrintThreads();

//// --------------------------------------------------------------------------
//// Allocator prototypes.
Expand Down
7 changes: 7 additions & 0 deletions compiler-rt/lib/lsan/lsan_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "lsan_common.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_placement_new.h"
#include "sanitizer_common/sanitizer_thread_history.h"
#include "sanitizer_common/sanitizer_thread_registry.h"
#include "sanitizer_common/sanitizer_tls_get_addr.h"

Expand Down Expand Up @@ -109,6 +110,12 @@ void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {
threads);
}

void PrintThreads() {
InternalScopedString out;
PrintThreadHistory(*thread_registry, out);
Report("%s\n", out.data());
}

void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs) {
GetThreadArgRetval().GetAllPtrsLocked(ptrs);
}
Expand Down
33 changes: 33 additions & 0 deletions compiler-rt/test/lsan/TestCases/print_threads.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// RUN: %clang_lsan %s -o %t && %env_lsan_opts=log_threads=1 %run %t 2>&1 | FileCheck %s

// XFAIL: hwasan

#include <assert.h>
#include <pthread.h>
#include <sanitizer/lsan_interface.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

pthread_barrier_t bar;

void *threadfn(void *arg) {
pthread_barrier_wait(&bar);
sleep(10000);
return 0;
}

int main(int argc, char *argv[]) {
pthread_t thread_id;
pthread_barrier_init(&bar, 0, 3);

pthread_create(&thread_id, 0, threadfn, 0);
pthread_create(&thread_id, 0, threadfn, 0);

pthread_barrier_wait(&bar);
return 0;
}

// CHECK: Thread T0/{{[0-9]+}} was created by T-1
// CHECK: Thread T1/{{[0-9]+}} was created by T0/
// CHECK: Thread T2/{{[0-9]+}} was created by T0/

0 comments on commit fa81868

Please sign in to comment.