[ASan/Win] Bandaid fix for PR22025 -- deadlocks when creating suspended threads

llvm-svn: 224823
This commit is contained in:
Timur Iskhodzhanov 2014-12-24 16:14:16 +00:00
parent 5a09b2cdeb
commit ced288f822
2 changed files with 40 additions and 15 deletions

View File

@ -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(), &param->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(&param.t, 0, memory_order_relaxed);
atomic_store(&param.is_registered, 0, memory_order_relaxed);
DWORD result = REAL(CreateThread)(security, stack_size, asan_thread_start,
&param, 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(&param.t, reinterpret_cast<uptr>(t), memory_order_release);
// The pthread_create interceptor waits here, so we do the same for
// consistency.
while (atomic_load(&param.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 {

View File

@ -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);
}