Skip to content

Commit a83eb04

Browse files
committed
[lsan] Add interceptor for pthread_detach.
This commit adds an interceptor for the pthread_detach function, calling into ThreadRegistry::DetachThread, allowing for thread contexts to be reused. Without this change, programs may fail when they create more than 8K threads. Fixes: https://bugs.llvm.org/show_bug.cgi?id=47389 Reviewed By: vitalybuka Differential Revision: https://reviews.llvm.org/D88184
1 parent 69c6f6b commit a83eb04

File tree

4 files changed

+39
-0
lines changed

4 files changed

+39
-0
lines changed

compiler-rt/lib/lsan/lsan_interceptors.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,15 @@ INTERCEPTOR(int, pthread_join, void *th, void **ret) {
476476
return res;
477477
}
478478

479+
INTERCEPTOR(int, pthread_detach, void *th) {
480+
ENSURE_LSAN_INITED;
481+
int tid = ThreadTid((uptr)th);
482+
int res = REAL(pthread_detach)(th);
483+
if (res == 0)
484+
ThreadDetach(tid);
485+
return res;
486+
}
487+
479488
INTERCEPTOR(void, _exit, int status) {
480489
if (status == 0 && HasReportedLeaks()) status = common_flags()->exitcode;
481490
REAL(_exit)(status);
@@ -508,6 +517,7 @@ void InitializeInterceptors() {
508517
LSAN_MAYBE_INTERCEPT_MALLINFO;
509518
LSAN_MAYBE_INTERCEPT_MALLOPT;
510519
INTERCEPT_FUNCTION(pthread_create);
520+
INTERCEPT_FUNCTION(pthread_detach);
511521
INTERCEPT_FUNCTION(pthread_join);
512522
INTERCEPT_FUNCTION(_exit);
513523

compiler-rt/lib/lsan/lsan_thread.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ u32 ThreadTid(uptr uid) {
8383
return thread_registry->FindThread(FindThreadByUid, (void *)uid);
8484
}
8585

86+
void ThreadDetach(u32 tid) {
87+
CHECK_NE(tid, kInvalidTid);
88+
thread_registry->DetachThread(tid, /* arg */ nullptr);
89+
}
90+
8691
void ThreadJoin(u32 tid) {
8792
CHECK_NE(tid, kInvalidTid);
8893
thread_registry->JoinThread(tid, /* arg */ nullptr);

compiler-rt/lib/lsan/lsan_thread.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ void InitializeMainThread();
4646

4747
u32 ThreadCreate(u32 tid, uptr uid, bool detached, void *arg = nullptr);
4848
void ThreadFinish();
49+
void ThreadDetach(u32 tid);
4950
void ThreadJoin(u32 tid);
5051
u32 ThreadTid(uptr uid);
5152

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Test that threads are reused.
2+
// RUN: %clangxx_lsan %s -o %t -lpthread && %run %t
3+
4+
#include <pthread.h>
5+
#include <stdlib.h>
6+
7+
// Number of threads to create. This value is greater than kMaxThreads in
8+
// lsan_thread.cpp so that we can test that thread contexts are not being
9+
// reused.
10+
static const size_t kTestThreads = 10000;
11+
12+
void *null_func(void *args) {
13+
return NULL;
14+
}
15+
16+
int main(void) {
17+
for (size_t i = 0; i < kTestThreads; i++) {
18+
pthread_t thread;
19+
pthread_create(&thread, NULL, null_func, NULL);
20+
pthread_detach(thread);
21+
}
22+
return 0;
23+
}

0 commit comments

Comments
 (0)