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) {
|
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);
|
ThreadStartParam *param = reinterpret_cast<ThreadStartParam *>(arg);
|
||||||
AsanThread *t = nullptr;
|
AsanThread *t = nullptr;
|
||||||
while ((t = reinterpret_cast<AsanThread *>(
|
while ((t = reinterpret_cast<AsanThread *>(
|
||||||
|
@ -203,6 +209,7 @@ static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
|
||||||
internal_sched_yield();
|
internal_sched_yield();
|
||||||
SetCurrentThread(t);
|
SetCurrentThread(t);
|
||||||
return t->ThreadStart(GetTid(), ¶m->is_registered);
|
return t->ThreadStart(GetTid(), ¶m->is_registered);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ASAN_INTERCEPT_PTHREAD_CREATE
|
#if ASAN_INTERCEPT_PTHREAD_CREATE
|
||||||
|
@ -807,23 +814,14 @@ INTERCEPTOR_WINAPI(DWORD, CreateThread,
|
||||||
if (flags()->strict_init_order)
|
if (flags()->strict_init_order)
|
||||||
StopInitOrderChecking();
|
StopInitOrderChecking();
|
||||||
GET_STACK_TRACE_THREAD;
|
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?
|
bool detached = false; // FIXME: how can we determine it on Windows?
|
||||||
ThreadStartParam param;
|
u32 current_tid = GetCurrentTidOrInvalid();
|
||||||
atomic_store(¶m.t, 0, memory_order_relaxed);
|
AsanThread *t =
|
||||||
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 =
|
|
||||||
AsanThread::Create(start_routine, arg, current_tid, &stack, detached);
|
AsanThread::Create(start_routine, arg, current_tid, &stack, detached);
|
||||||
atomic_store(¶m.t, reinterpret_cast<uptr>(t), memory_order_release);
|
return REAL(CreateThread)(security, stack_size,
|
||||||
// The pthread_create interceptor waits here, so we do the same for
|
asan_thread_start, t, thr_flags, tid);
|
||||||
// consistency.
|
|
||||||
while (atomic_load(¶m.is_registered, memory_order_acquire) == 0)
|
|
||||||
internal_sched_yield();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace __asan {
|
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