forked from OSchip/llvm-project
[ASan/Win] Bandaid fix for PR22025 -- deadlocks when creating suspended threads
llvm-svn: 224823
This commit is contained in:
parent
5a09b2cdeb
commit
ced288f822
|
@ -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<ThreadStartParam *>(arg);
|
||||
AsanThread *t = nullptr;
|
||||
while ((t = reinterpret_cast<AsanThread *>(
|
||||
|
@ -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<uptr>(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 {
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// RUN: %clang_cl_asan -O0 %s -Fe%t
|
||||
// RUN: %run %t
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue