Skip to content

Commit 22bcc77

Browse files
committed
[asan][win] Fix ExitThread leak
Use tls to store the memory created by `VirtualAlloc`, Then intercept `ExitThread` and release the memory
1 parent dd59198 commit 22bcc77

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

compiler-rt/lib/asan/asan_win.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,25 @@ struct ThreadStartParams {
136136
void *arg;
137137
};
138138

139+
static atomic_uint32_t g_native_tls_key{TLS_OUT_OF_INDEXES};
140+
141+
bool AllocTLS(DWORD *key) {
142+
DWORD value = TlsAlloc();
143+
if (value != TLS_OUT_OF_INDEXES) {
144+
*key = value;
145+
return true;
146+
}
147+
return false;
148+
}
149+
139150
static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
151+
DWORD key = atomic_load(&g_native_tls_key, memory_order_relaxed);
152+
if (key == TLS_OUT_OF_INDEXES) {
153+
CHECK(AllocTLS(&key));
154+
atomic_store(&g_native_tls_key, key, memory_order_release);
155+
}
156+
CHECK(key != TLS_OUT_OF_INDEXES);
157+
TlsSetValue(key, arg);
140158
AsanThread *t = (AsanThread *)arg;
141159
SetCurrentThread(t);
142160
t->ThreadStart(GetTid());
@@ -145,7 +163,6 @@ static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
145163
t->GetStartData(params);
146164

147165
auto res = (*params.start_routine)(params.arg);
148-
t->Destroy(); // POSIX calls this from TSD destructor.
149166
return res;
150167
}
151168

@@ -166,6 +183,15 @@ INTERCEPTOR_WINAPI(HANDLE, CreateThread, LPSECURITY_ATTRIBUTES security,
166183
thr_flags, tid);
167184
}
168185

186+
INTERCEPTOR_WINAPI(void, ExitThread, DWORD dwExitCode) {
187+
DWORD key = atomic_load(&g_native_tls_key, memory_order_relaxed);
188+
AsanThread *t = (AsanThread *)TlsGetValue(key);
189+
if (t) {
190+
t->Destroy();
191+
}
192+
REAL(ExitThread)(dwExitCode);
193+
}
194+
169195
// }}}
170196

171197
namespace __asan {
@@ -181,6 +207,7 @@ void InitializePlatformInterceptors() {
181207
(LPCWSTR)&InitializePlatformInterceptors, &pinned));
182208

183209
ASAN_INTERCEPT_FUNC(CreateThread);
210+
ASAN_INTERCEPT_FUNC(ExitThread);
184211
ASAN_INTERCEPT_FUNC(SetUnhandledExceptionFilter);
185212

186213
#ifdef _WIN64

0 commit comments

Comments
 (0)