Skip to content

Commit 38fd180

Browse files
frobtechpetrhosek
authored andcommitted
[lsan] Factor pthread-specific assumptions out of thread tracking code
This is a small refactoring to prepare for porting LSan to Fuchsia. Factor out parts of lsan_thread.{cpp,h} that don't apply to Fuchsia. Since existing supported systems are POSIX-based, the affected code is moved to lsan_posix.{cpp.h}. Patch By: mcgrathr Differential Revision: https://reviews.llvm.org/D73309
1 parent aae707c commit 38fd180

File tree

8 files changed

+182
-99
lines changed

8 files changed

+182
-99
lines changed

compiler-rt/lib/lsan/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ set(LSAN_COMMON_SOURCES
1212
set(LSAN_SOURCES
1313
lsan.cpp
1414
lsan_allocator.cpp
15-
lsan_linux.cpp
1615
lsan_interceptors.cpp
16+
lsan_linux.cpp
1717
lsan_mac.cpp
1818
lsan_malloc_mac.cpp
19+
lsan_posix.cpp
1920
lsan_preinit.cpp
2021
lsan_thread.cpp
2122
)

compiler-rt/lib/lsan/lsan.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,7 @@ extern "C" void __lsan_init() {
114114
InitializeInterceptors();
115115
InitializeThreadRegistry();
116116
InstallDeadlySignalHandlers(LsanOnDeadlySignal);
117-
u32 tid = ThreadCreate(0, 0, true);
118-
CHECK_EQ(tid, 0);
119-
ThreadStart(tid, GetTid());
120-
SetCurrentThread(tid);
117+
InitializeMainThread();
121118

122119
if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit)
123120
Atexit(DoLeakCheck);

compiler-rt/lib/lsan/lsan.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
#include "lsan_thread.h"
15+
#if SANITIZER_POSIX
16+
#include "lsan_posix.h"
17+
#endif
1518
#include "sanitizer_common/sanitizer_flags.h"
1619
#include "sanitizer_common/sanitizer_stacktrace.h"
1720

compiler-rt/lib/lsan/lsan_interceptors.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
#include "sanitizer_common/sanitizer_platform_interceptors.h"
2323
#include "sanitizer_common/sanitizer_platform_limits_netbsd.h"
2424
#include "sanitizer_common/sanitizer_platform_limits_posix.h"
25+
#if SANITIZER_POSIX
2526
#include "sanitizer_common/sanitizer_posix.h"
27+
#endif
2628
#include "sanitizer_common/sanitizer_tls_get_addr.h"
2729
#include "lsan.h"
2830
#include "lsan_allocator.h"
@@ -416,7 +418,6 @@ extern "C" void *__lsan_thread_start_func(void *arg) {
416418
int tid = 0;
417419
while ((tid = atomic_load(&p->tid, memory_order_acquire)) == 0)
418420
internal_sched_yield();
419-
SetCurrentThread(tid);
420421
ThreadStart(tid, GetTid());
421422
atomic_store(&p->tid, 0, memory_order_release);
422423
return callback(param);

compiler-rt/lib/lsan/lsan_posix.cpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//=-- lsan_posix.cpp -----------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===---------------------------------------------------------------------===//
8+
//
9+
// This file is a part of LeakSanitizer.
10+
// Standalone LSan RTL code common to POSIX-like systems.
11+
//
12+
//===---------------------------------------------------------------------===//
13+
14+
#include "sanitizer_common/sanitizer_platform.h"
15+
16+
#if SANITIZER_POSIX
17+
#include "lsan.h"
18+
#include "lsan_allocator.h"
19+
#include "sanitizer_common/sanitizer_stacktrace.h"
20+
#include "sanitizer_common/sanitizer_tls_get_addr.h"
21+
22+
namespace __lsan {
23+
24+
ThreadContext::ThreadContext(int tid) : ThreadContextLsanBase(tid) {}
25+
26+
struct OnStartedArgs {
27+
uptr stack_begin;
28+
uptr stack_end;
29+
uptr cache_begin;
30+
uptr cache_end;
31+
uptr tls_begin;
32+
uptr tls_end;
33+
DTLS *dtls;
34+
};
35+
36+
void ThreadContext::OnStarted(void *arg) {
37+
auto args = reinterpret_cast<const OnStartedArgs *>(arg);
38+
stack_begin_ = args->stack_begin;
39+
stack_end_ = args->stack_end;
40+
tls_begin_ = args->tls_begin;
41+
tls_end_ = args->tls_end;
42+
cache_begin_ = args->cache_begin;
43+
cache_end_ = args->cache_end;
44+
dtls_ = args->dtls;
45+
}
46+
47+
void ThreadStart(u32 tid, tid_t os_id, ThreadType thread_type) {
48+
OnStartedArgs args;
49+
uptr stack_size = 0;
50+
uptr tls_size = 0;
51+
GetThreadStackAndTls(tid == 0, &args.stack_begin, &stack_size,
52+
&args.tls_begin, &tls_size);
53+
args.stack_end = args.stack_begin + stack_size;
54+
args.tls_end = args.tls_begin + tls_size;
55+
GetAllocatorCacheRange(&args.cache_begin, &args.cache_end);
56+
args.dtls = DTLS_Get();
57+
ThreadContextLsanBase::ThreadStart(tid, os_id, thread_type, &args);
58+
}
59+
60+
bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end,
61+
uptr *tls_begin, uptr *tls_end, uptr *cache_begin,
62+
uptr *cache_end, DTLS **dtls) {
63+
ThreadContext *context = static_cast<ThreadContext *>(
64+
GetThreadRegistryLocked()->FindThreadContextByOsIDLocked(os_id));
65+
if (!context)
66+
return false;
67+
*stack_begin = context->stack_begin();
68+
*stack_end = context->stack_end();
69+
*tls_begin = context->tls_begin();
70+
*tls_end = context->tls_end();
71+
*cache_begin = context->cache_begin();
72+
*cache_end = context->cache_end();
73+
*dtls = context->dtls();
74+
return true;
75+
}
76+
77+
void InitializeMainThread() {
78+
u32 tid = ThreadCreate(0, 0, true);
79+
CHECK_EQ(tid, 0);
80+
ThreadStart(tid, GetTid());
81+
}
82+
83+
} // namespace __lsan
84+
85+
#endif // SANITIZER_POSIX

compiler-rt/lib/lsan/lsan_posix.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//=-- lsan_posix.h -----------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===---------------------------------------------------------------------===//
8+
//
9+
// This file is a part of LeakSanitizer.
10+
// Standalone LSan RTL code common to POSIX-like systems.
11+
//
12+
//===---------------------------------------------------------------------===//
13+
14+
#ifndef LSAN_POSIX_H
15+
#define LSAN_POSIX_H
16+
17+
#include "lsan_thread.h"
18+
#include "sanitizer_common/sanitizer_platform.h"
19+
20+
#if !SANITIZER_POSIX
21+
#error "lsan_posix.h is used only on POSIX-like systems (SANITIZER_POSIX)"
22+
#endif
23+
24+
namespace __sanitizer {
25+
struct DTLS;
26+
}
27+
28+
namespace __lsan {
29+
30+
class ThreadContext : public ThreadContextLsanBase {
31+
public:
32+
explicit ThreadContext(int tid);
33+
void OnStarted(void *arg) override;
34+
uptr tls_begin() { return tls_begin_; }
35+
uptr tls_end() { return tls_end_; }
36+
DTLS *dtls() { return dtls_; }
37+
38+
private:
39+
uptr tls_begin_ = 0;
40+
uptr tls_end_ = 0;
41+
DTLS *dtls_ = nullptr;
42+
};
43+
44+
void ThreadStart(u32 tid, tid_t os_id,
45+
ThreadType thread_type = ThreadType::Regular);
46+
47+
} // namespace __lsan
48+
49+
#endif // LSAN_POSIX_H

compiler-rt/lib/lsan/lsan_thread.cpp

Lines changed: 23 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -13,80 +13,48 @@
1313

1414
#include "lsan_thread.h"
1515

16+
#include "lsan.h"
17+
#include "lsan_allocator.h"
18+
#include "lsan_common.h"
1619
#include "sanitizer_common/sanitizer_common.h"
1720
#include "sanitizer_common/sanitizer_placement_new.h"
1821
#include "sanitizer_common/sanitizer_thread_registry.h"
1922
#include "sanitizer_common/sanitizer_tls_get_addr.h"
20-
#include "lsan_allocator.h"
21-
#include "lsan_common.h"
2223

2324
namespace __lsan {
2425

2526
static ThreadRegistry *thread_registry;
2627

2728
static ThreadContextBase *CreateThreadContext(u32 tid) {
2829
void *mem = MmapOrDie(sizeof(ThreadContext), "ThreadContext");
29-
return new(mem) ThreadContext(tid);
30+
return new (mem) ThreadContext(tid);
3031
}
3132

3233
static const uptr kMaxThreads = 1 << 13;
3334
static const uptr kThreadQuarantineSize = 64;
3435

3536
void InitializeThreadRegistry() {
3637
static ALIGNED(64) char thread_registry_placeholder[sizeof(ThreadRegistry)];
37-
thread_registry = new(thread_registry_placeholder)
38-
ThreadRegistry(CreateThreadContext, kMaxThreads, kThreadQuarantineSize);
38+
thread_registry = new (thread_registry_placeholder)
39+
ThreadRegistry(CreateThreadContext, kMaxThreads, kThreadQuarantineSize);
3940
}
4041

41-
ThreadContext::ThreadContext(int tid)
42-
: ThreadContextBase(tid),
43-
stack_begin_(0),
44-
stack_end_(0),
45-
cache_begin_(0),
46-
cache_end_(0),
47-
tls_begin_(0),
48-
tls_end_(0),
49-
dtls_(nullptr) {}
50-
51-
struct OnStartedArgs {
52-
uptr stack_begin, stack_end,
53-
cache_begin, cache_end,
54-
tls_begin, tls_end;
55-
DTLS *dtls;
56-
};
57-
58-
void ThreadContext::OnStarted(void *arg) {
59-
OnStartedArgs *args = reinterpret_cast<OnStartedArgs *>(arg);
60-
stack_begin_ = args->stack_begin;
61-
stack_end_ = args->stack_end;
62-
tls_begin_ = args->tls_begin;
63-
tls_end_ = args->tls_end;
64-
cache_begin_ = args->cache_begin;
65-
cache_end_ = args->cache_end;
66-
dtls_ = args->dtls;
67-
}
42+
ThreadContextLsanBase::ThreadContextLsanBase(int tid)
43+
: ThreadContextBase(tid) {}
6844

69-
void ThreadContext::OnFinished() {
45+
void ThreadContextLsanBase::OnFinished() {
7046
AllocatorThreadFinish();
7147
DTLS_Destroy();
7248
}
7349

74-
u32 ThreadCreate(u32 parent_tid, uptr user_id, bool detached) {
75-
return thread_registry->CreateThread(user_id, detached, parent_tid,
76-
/* arg */ nullptr);
50+
u32 ThreadCreate(u32 parent_tid, uptr user_id, bool detached, void *arg) {
51+
return thread_registry->CreateThread(user_id, detached, parent_tid, arg);
7752
}
7853

79-
void ThreadStart(u32 tid, tid_t os_id, ThreadType thread_type) {
80-
OnStartedArgs args;
81-
uptr stack_size = 0;
82-
uptr tls_size = 0;
83-
GetThreadStackAndTls(tid == 0, &args.stack_begin, &stack_size,
84-
&args.tls_begin, &tls_size);
85-
args.stack_end = args.stack_begin + stack_size;
86-
args.tls_end = args.tls_begin + tls_size;
87-
GetAllocatorCacheRange(&args.cache_begin, &args.cache_end);
88-
args.dtls = DTLS_Get();
89-
thread_registry->StartThread(tid, os_id, thread_type, &args);
54+
void ThreadContextLsanBase::ThreadStart(u32 tid, tid_t os_id,
55+
ThreadType thread_type, void *arg) {
56+
thread_registry->StartThread(tid, os_id, thread_type, arg);
57+
SetCurrentThread(tid);
9058
}
9159

9260
void ThreadFinish() {
@@ -95,7 +63,8 @@ void ThreadFinish() {
9563
}
9664

9765
ThreadContext *CurrentThreadContext() {
98-
if (!thread_registry) return nullptr;
66+
if (!thread_registry)
67+
return nullptr;
9968
if (GetCurrentThread() == kInvalidTid)
10069
return nullptr;
10170
// No lock needed when getting current thread.
@@ -111,12 +80,12 @@ static bool FindThreadByUid(ThreadContextBase *tctx, void *arg) {
11180
}
11281

11382
u32 ThreadTid(uptr uid) {
114-
return thread_registry->FindThread(FindThreadByUid, (void*)uid);
83+
return thread_registry->FindThread(FindThreadByUid, (void *)uid);
11584
}
11685

11786
void ThreadJoin(u32 tid) {
11887
CHECK_NE(tid, kInvalidTid);
119-
thread_registry->JoinThread(tid, /* arg */nullptr);
88+
thread_registry->JoinThread(tid, /* arg */ nullptr);
12089
}
12190

12291
void EnsureMainThreadIDIsCorrect() {
@@ -126,37 +95,16 @@ void EnsureMainThreadIDIsCorrect() {
12695

12796
///// Interface to the common LSan module. /////
12897

129-
bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end,
130-
uptr *tls_begin, uptr *tls_end, uptr *cache_begin,
131-
uptr *cache_end, DTLS **dtls) {
132-
ThreadContext *context = static_cast<ThreadContext *>(
133-
thread_registry->FindThreadContextByOsIDLocked(os_id));
134-
if (!context) return false;
135-
*stack_begin = context->stack_begin();
136-
*stack_end = context->stack_end();
137-
*tls_begin = context->tls_begin();
138-
*tls_end = context->tls_end();
139-
*cache_begin = context->cache_begin();
140-
*cache_end = context->cache_end();
141-
*dtls = context->dtls();
142-
return true;
143-
}
144-
14598
void ForEachExtraStackRange(tid_t os_id, RangeIteratorCallback callback,
146-
void *arg) {
147-
}
99+
void *arg) {}
148100

149-
void LockThreadRegistry() {
150-
thread_registry->Lock();
151-
}
101+
void LockThreadRegistry() { thread_registry->Lock(); }
152102

153-
void UnlockThreadRegistry() {
154-
thread_registry->Unlock();
155-
}
103+
void UnlockThreadRegistry() { thread_registry->Unlock(); }
156104

157105
ThreadRegistry *GetThreadRegistryLocked() {
158106
thread_registry->CheckLocked();
159107
return thread_registry;
160108
}
161109

162-
} // namespace __lsan
110+
} // namespace __lsan

0 commit comments

Comments
 (0)