@@ -136,7 +136,25 @@ struct ThreadStartParams {
136
136
void *arg;
137
137
};
138
138
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
+
139
150
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);
140
158
AsanThread *t = (AsanThread *)arg;
141
159
SetCurrentThread (t);
142
160
t->ThreadStart (GetTid ());
@@ -145,7 +163,6 @@ static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
145
163
t->GetStartData (params);
146
164
147
165
auto res = (*params.start_routine )(params.arg );
148
- t->Destroy (); // POSIX calls this from TSD destructor.
149
166
return res;
150
167
}
151
168
@@ -166,6 +183,15 @@ INTERCEPTOR_WINAPI(HANDLE, CreateThread, LPSECURITY_ATTRIBUTES security,
166
183
thr_flags, tid);
167
184
}
168
185
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
+
169
195
// }}}
170
196
171
197
namespace __asan {
@@ -181,6 +207,7 @@ void InitializePlatformInterceptors() {
181
207
(LPCWSTR)&InitializePlatformInterceptors, &pinned));
182
208
183
209
ASAN_INTERCEPT_FUNC (CreateThread);
210
+ ASAN_INTERCEPT_FUNC (ExitThread);
184
211
ASAN_INTERCEPT_FUNC (SetUnhandledExceptionFilter);
185
212
186
213
#ifdef _WIN64
0 commit comments