Skip to content

Commit 9e3aeaa

Browse files
vitalybukaDanielCChen
authored andcommitted
[NFC][sanitizer][asan] Promote stack_id into ThreadContextBase (llvm#111917)
`parent_id` and `stack_id` represent location where the thread was created, so it's reasonable to keep them togeter. For now, only Asan and MemProf use `stack_id`, but it will be halpfull to print thread origin from other sanitizers as well. For llvm#111948
1 parent 5a2bfb2 commit 9e3aeaa

8 files changed

+43
-42
lines changed

compiler-rt/lib/asan/asan_fuchsia.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,7 @@ static AsanThread *CreateAsanThread(StackTrace *stack, u32 parent_tid,
121121
// In lieu of AsanThread::Create.
122122
AsanThread *thread = (AsanThread *)MmapOrDie(AsanThreadMmapSize(), __func__);
123123

124-
AsanThreadContext::CreateThreadContextArgs args = {thread, stack};
125-
u32 tid = asanThreadRegistry().CreateThread(0, detached, parent_tid, &args);
124+
u32 tid = asanThreadRegistry().CreateThread(0, detached, parent_tid, thread);
126125
asanThreadRegistry().SetThreadName(tid, name);
127126

128127
return thread;

compiler-rt/lib/asan/asan_thread.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,7 @@ namespace __asan {
2828
// AsanThreadContext implementation.
2929

3030
void AsanThreadContext::OnCreated(void *arg) {
31-
CreateThreadContextArgs *args = static_cast<CreateThreadContextArgs *>(arg);
32-
if (args->stack)
33-
stack_id = StackDepotPut(*args->stack);
34-
thread = args->thread;
31+
thread = static_cast<AsanThread *>(arg);
3532
thread->set_context(this);
3633
}
3734

@@ -106,8 +103,8 @@ AsanThread *AsanThread::Create(const void *start_data, uptr data_size,
106103
CHECK_LE(data_size, availible_size);
107104
internal_memcpy(thread->start_data_, start_data, data_size);
108105
}
109-
AsanThreadContext::CreateThreadContextArgs args = {thread, stack};
110-
asanThreadRegistry().CreateThread(0, detached, parent_tid, &args);
106+
asanThreadRegistry().CreateThread(0, detached, parent_tid,
107+
stack ? StackDepotPut(*stack) : 0, thread);
111108

112109
return thread;
113110
}

compiler-rt/lib/asan/asan_thread.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,16 @@ class AsanThread;
3636
class AsanThreadContext final : public ThreadContextBase {
3737
public:
3838
explicit AsanThreadContext(int tid)
39-
: ThreadContextBase(tid), announced(false),
40-
destructor_iterations(GetPthreadDestructorIterations()), stack_id(0),
39+
: ThreadContextBase(tid),
40+
announced(false),
41+
destructor_iterations(GetPthreadDestructorIterations()),
4142
thread(nullptr) {}
4243
bool announced;
4344
u8 destructor_iterations;
44-
u32 stack_id;
4545
AsanThread *thread;
4646

4747
void OnCreated(void *arg) override;
4848
void OnFinished() override;
49-
50-
struct CreateThreadContextArgs {
51-
AsanThread *thread;
52-
StackTrace *stack;
53-
};
5449
};
5550

5651
// AsanThreadContext objects are never freed, so we need many of them.

compiler-rt/lib/memprof/memprof_thread.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,7 @@ namespace __memprof {
2525
// MemprofThreadContext implementation.
2626

2727
void MemprofThreadContext::OnCreated(void *arg) {
28-
CreateThreadContextArgs *args = static_cast<CreateThreadContextArgs *>(arg);
29-
if (args->stack)
30-
stack_id = StackDepotPut(*args->stack);
31-
thread = args->thread;
28+
thread = static_cast<MemprofThread *>(arg);
3229
thread->set_context(this);
3330
}
3431

@@ -79,8 +76,8 @@ MemprofThread *MemprofThread::Create(thread_callback_t start_routine, void *arg,
7976
MemprofThread *thread = (MemprofThread *)MmapOrDie(size, __func__);
8077
thread->start_routine_ = start_routine;
8178
thread->arg_ = arg;
82-
MemprofThreadContext::CreateThreadContextArgs args = {thread, stack};
83-
memprofThreadRegistry().CreateThread(0, detached, parent_tid, &args);
79+
memprofThreadRegistry().CreateThread(
80+
0, detached, parent_tid, stack ? StackDepotPut(*stack) : 0, thread);
8481

8582
return thread;
8683
}

compiler-rt/lib/memprof/memprof_thread.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,14 @@ class MemprofThread;
3434
struct MemprofThreadContext final : public ThreadContextBase {
3535
explicit MemprofThreadContext(int tid)
3636
: ThreadContextBase(tid), announced(false),
37-
destructor_iterations(GetPthreadDestructorIterations()), stack_id(0),
37+
destructor_iterations(GetPthreadDestructorIterations()),
3838
thread(nullptr) {}
3939
bool announced;
4040
u8 destructor_iterations;
41-
u32 stack_id;
4241
MemprofThread *thread;
4342

4443
void OnCreated(void *arg) override;
4544
void OnFinished() override;
46-
47-
struct CreateThreadContextArgs {
48-
MemprofThread *thread;
49-
StackTrace *stack;
50-
};
5145
};
5246

5347
// MemprofThreadContext objects are never freed, so we need many of them.

compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ ThreadContextBase::ThreadContextBase(u32 tid)
2727
detached(false),
2828
thread_type(ThreadType::Regular),
2929
parent_tid(0),
30+
stack_id(0),
3031
next(0) {
3132
name[0] = '\0';
3233
atomic_store(&thread_destroyed, 0, memory_order_release);
@@ -88,14 +89,17 @@ void ThreadContextBase::SetStarted(tid_t _os_id, ThreadType _thread_type,
8889
}
8990

9091
void ThreadContextBase::SetCreated(uptr _user_id, u64 _unique_id,
91-
bool _detached, u32 _parent_tid, void *arg) {
92+
bool _detached, u32 _parent_tid,
93+
u32 _stack_tid, void *arg) {
9294
status = ThreadStatusCreated;
9395
user_id = _user_id;
9496
unique_id = _unique_id;
9597
detached = _detached;
9698
// Parent tid makes no sense for the main thread.
97-
if (tid != kMainTid)
99+
if (tid != kMainTid) {
98100
parent_tid = _parent_tid;
101+
stack_id = _stack_tid;
102+
}
99103
OnCreated(arg);
100104
}
101105

@@ -143,7 +147,7 @@ uptr ThreadRegistry::GetMaxAliveThreads() {
143147
}
144148

145149
u32 ThreadRegistry::CreateThread(uptr user_id, bool detached, u32 parent_tid,
146-
void *arg) {
150+
u32 stack_tid, void *arg) {
147151
ThreadRegistryLock l(this);
148152
u32 tid = kInvalidTid;
149153
ThreadContextBase *tctx = QuarantinePop();
@@ -181,7 +185,8 @@ u32 ThreadRegistry::CreateThread(uptr user_id, bool detached, u32 parent_tid,
181185
// positives later (e.g. if we join a wrong thread).
182186
CHECK(live_.try_emplace(user_id, tid).second);
183187
}
184-
tctx->SetCreated(user_id, total_threads_++, detached, parent_tid, arg);
188+
tctx->SetCreated(user_id, total_threads_++, detached, parent_tid, stack_tid,
189+
arg);
185190
return tid;
186191
}
187192

compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class ThreadContextBase {
5252
ThreadType thread_type;
5353

5454
u32 parent_tid;
55+
u32 stack_id;
5556
ThreadContextBase *next; // For storing thread contexts in a list.
5657

5758
atomic_uint32_t thread_destroyed; // To address race of Joined vs Finished
@@ -63,7 +64,7 @@ class ThreadContextBase {
6364
void SetFinished();
6465
void SetStarted(tid_t _os_id, ThreadType _thread_type, void *arg);
6566
void SetCreated(uptr _user_id, u64 _unique_id, bool _detached,
66-
u32 _parent_tid, void *arg);
67+
u32 _parent_tid, u32 _stack_tid, void *arg);
6768
void Reset();
6869

6970
void SetDestroyed();
@@ -106,7 +107,11 @@ class SANITIZER_MUTEX ThreadRegistry {
106107

107108
u32 NumThreadsLocked() const { return threads_.size(); }
108109

109-
u32 CreateThread(uptr user_id, bool detached, u32 parent_tid, void *arg);
110+
u32 CreateThread(uptr user_id, bool detached, u32 parent_tid, u32 stack_tid,
111+
void *arg);
112+
u32 CreateThread(uptr user_id, bool detached, u32 parent_tid, void *arg) {
113+
return CreateThread(user_id, detached, parent_tid, 0, arg);
114+
}
110115

111116
typedef void (*ThreadCallback)(ThreadContextBase *tctx, void *arg);
112117
// Invokes callback with a specified arg for each thread context.

compiler-rt/lib/sanitizer_common/tests/sanitizer_thread_registry_test.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,12 @@ static void MarkUidAsPresent(ThreadContextBase *tctx, void *arg) {
6464

6565
static void TestRegistry(ThreadRegistry *registry, bool has_quarantine) {
6666
// Create and start a main thread.
67-
EXPECT_EQ(0U, registry->CreateThread(get_uid(0), true, -1, 0));
67+
EXPECT_EQ(0U, registry->CreateThread(get_uid(0), true, -1, 0, nullptr));
6868
registry->StartThread(0, 0, ThreadType::Regular, 0);
6969
// Create a bunch of threads.
7070
for (u32 i = 1; i <= 10; i++) {
71-
EXPECT_EQ(i, registry->CreateThread(get_uid(i), is_detached(i), 0, 0));
71+
EXPECT_EQ(i, registry->CreateThread(get_uid(i), is_detached(i), 100 + i,
72+
200 + i, nullptr));
7273
}
7374
CheckThreadQuantity(registry, 11, 1, 11);
7475
// Start some of them.
@@ -88,19 +89,27 @@ static void TestRegistry(ThreadRegistry *registry, bool has_quarantine) {
8889
std::vector<u32> new_tids;
8990
for (u32 i = 11; i <= 15; i++) {
9091
new_tids.push_back(
91-
registry->CreateThread(get_uid(i), is_detached(i), 0, 0));
92+
registry->CreateThread(get_uid(i), is_detached(i), 0, 0, nullptr));
9293
}
9394
ASSERT_LE(kRegistryQuarantine, 5U);
94-
u32 exp_total = 16 - (has_quarantine ? 5 - kRegistryQuarantine : 0);
95+
u32 exp_total = 16 - (has_quarantine ? 5 - kRegistryQuarantine : 0);
9596
CheckThreadQuantity(registry, exp_total, 6, 11);
9697
// Test SetThreadName and FindThread.
9798
registry->SetThreadName(6, "six");
9899
registry->SetThreadName(7, "seven");
99-
EXPECT_EQ(7U, registry->FindThread(HasName, (void*)"seven"));
100+
EXPECT_EQ(7U, registry->FindThread(HasName, (void *)"seven"));
100101
EXPECT_EQ(kInvalidTid, registry->FindThread(HasName, (void *)"none"));
101-
EXPECT_EQ(0U, registry->FindThread(HasUid, (void*)get_uid(0)));
102-
EXPECT_EQ(10U, registry->FindThread(HasUid, (void*)get_uid(10)));
102+
EXPECT_EQ(0U, registry->FindThread(HasUid, (void *)get_uid(0)));
103+
EXPECT_EQ(10U, registry->FindThread(HasUid, (void *)get_uid(10)));
103104
EXPECT_EQ(kInvalidTid, registry->FindThread(HasUid, (void *)0x1234));
105+
EXPECT_EQ(7U,
106+
registry->FindThread([](ThreadContextBase *tctx,
107+
void *) { return tctx->parent_tid == 107; },
108+
nullptr));
109+
EXPECT_EQ(8U,
110+
registry->FindThread([](ThreadContextBase *tctx,
111+
void *) { return tctx->stack_id == 208; },
112+
nullptr));
104113
// Detach and finish and join remaining threads.
105114
for (u32 i = 6; i <= 10; i++) {
106115
registry->DetachThread(i, 0);

0 commit comments

Comments
 (0)