@@ -136,7 +136,32 @@ 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
+ // Leak global key
154
+ CHECK (AllocTLS (&key));
155
+ DWORD old_key = TLS_OUT_OF_INDEXES;
156
+ // Prevent another thread already store
157
+ if (!atomic_compare_exchange_strong (&g_native_tls_key, (u32 *)&old_key,
158
+ (u32 )key, memory_order_relaxed)) {
159
+ TlsFree (key);
160
+ key = atomic_load (&g_native_tls_key, memory_order_relaxed);
161
+ }
162
+ }
163
+ CHECK (key != TLS_OUT_OF_INDEXES);
164
+ TlsSetValue (key, arg);
140
165
AsanThread *t = (AsanThread *)arg;
141
166
SetCurrentThread (t);
142
167
t->ThreadStart (GetTid ());
@@ -145,7 +170,6 @@ static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
145
170
t->GetStartData (params);
146
171
147
172
auto res = (*params.start_routine )(params.arg );
148
- t->Destroy (); // POSIX calls this from TSD destructor.
149
173
return res;
150
174
}
151
175
@@ -166,6 +190,15 @@ INTERCEPTOR_WINAPI(HANDLE, CreateThread, LPSECURITY_ATTRIBUTES security,
166
190
thr_flags, tid);
167
191
}
168
192
193
+ INTERCEPTOR_WINAPI (void , ExitThread, DWORD dwExitCode) {
194
+ DWORD key = atomic_load (&g_native_tls_key, memory_order_relaxed);
195
+ AsanThread *t = (AsanThread *)TlsGetValue (key);
196
+ if (t) {
197
+ t->Destroy ();
198
+ }
199
+ REAL (ExitThread)(dwExitCode);
200
+ }
201
+
169
202
// }}}
170
203
171
204
namespace __asan {
@@ -181,6 +214,7 @@ void InitializePlatformInterceptors() {
181
214
(LPCWSTR)&InitializePlatformInterceptors, &pinned));
182
215
183
216
ASAN_INTERCEPT_FUNC (CreateThread);
217
+ ASAN_INTERCEPT_FUNC (ExitThread);
184
218
ASAN_INTERCEPT_FUNC (SetUnhandledExceptionFilter);
185
219
186
220
#ifdef _WIN64
0 commit comments