diff --git a/compiler-rt/lib/asan/asan_interceptors.cc b/compiler-rt/lib/asan/asan_interceptors.cc index a311bfeb240d..32c08ff56056 100644 --- a/compiler-rt/lib/asan/asan_interceptors.cc +++ b/compiler-rt/lib/asan/asan_interceptors.cc @@ -196,6 +196,12 @@ struct ThreadStartParam { }; static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) { +#if SANITIZER_WINDOWS + // FIXME: this is a bandaid fix for PR22025. + AsanThread *t = (AsanThread*)arg; + SetCurrentThread(t); + return t->ThreadStart(GetTid(), /* signal_thread_is_registered */ nullptr); +#else ThreadStartParam *param = reinterpret_cast(arg); AsanThread *t = nullptr; while ((t = reinterpret_cast( @@ -203,6 +209,7 @@ static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) { internal_sched_yield(); SetCurrentThread(t); return t->ThreadStart(GetTid(), ¶m->is_registered); +#endif } #if ASAN_INTERCEPT_PTHREAD_CREATE @@ -807,23 +814,14 @@ INTERCEPTOR_WINAPI(DWORD, CreateThread, if (flags()->strict_init_order) StopInitOrderChecking(); GET_STACK_TRACE_THREAD; + // FIXME: The CreateThread interceptor is not the same as a pthread_create + // one. This is a bandaid fix for PR22025. bool detached = false; // FIXME: how can we determine it on Windows? - ThreadStartParam param; - atomic_store(¶m.t, 0, memory_order_relaxed); - atomic_store(¶m.is_registered, 0, memory_order_relaxed); - DWORD result = REAL(CreateThread)(security, stack_size, asan_thread_start, - ¶m, thr_flags, tid); - if (result) { - u32 current_tid = GetCurrentTidOrInvalid(); - AsanThread *t = + u32 current_tid = GetCurrentTidOrInvalid(); + AsanThread *t = AsanThread::Create(start_routine, arg, current_tid, &stack, detached); - atomic_store(¶m.t, reinterpret_cast(t), memory_order_release); - // The pthread_create interceptor waits here, so we do the same for - // consistency. - while (atomic_load(¶m.is_registered, memory_order_acquire) == 0) - internal_sched_yield(); - } - return result; + return REAL(CreateThread)(security, stack_size, + asan_thread_start, t, thr_flags, tid); } namespace __asan { diff --git a/compiler-rt/test/asan/TestCases/Windows/thread_suspended.cc b/compiler-rt/test/asan/TestCases/Windows/thread_suspended.cc new file mode 100644 index 000000000000..47e4f9d5d19b --- /dev/null +++ b/compiler-rt/test/asan/TestCases/Windows/thread_suspended.cc @@ -0,0 +1,27 @@ +// RUN: %clang_cl_asan -O0 %s -Fe%t +// RUN: %run %t + +#include + +DWORD WINAPI thread_proc(void *) { + volatile char stack_buffer[42]; + for (int i = 0; i < sizeof(stack_buffer); ++i) + stack_buffer[i] = 42; + return 0x42; +} + +int main() { + DWORD exitcode; + HANDLE thr = CreateThread(NULL, 0, thread_proc, NULL, CREATE_SUSPENDED, NULL); + ResumeThread(thr); + if (thr == 0) + return 1; + if (WAIT_OBJECT_0 != WaitForSingleObject(thr, INFINITE)) + return 2; + + GetExitCodeThread(thr, &exitcode); + if (exitcode != 0x42) + return 3; + CloseHandle(thr); +} +