2019-03-09 23:34:50 +03:00
|
|
|
[winasan] Unpoison the stack in NtTerminateThread
|
|
|
|
|
2019-09-21 17:26:53 +03:00
|
|
|
In long-running builds we've seen some ASan complaints during thread creation
|
|
|
|
that we suspect are due to leftover poisoning from previous threads whose stacks
|
|
|
|
occupied that memory. This patch adds a hook that unpoisons the stack just
|
|
|
|
before the NtTerminateThread syscall.
|
2019-03-09 23:34:50 +03:00
|
|
|
|
|
|
|
Differential Revision: https://reviews.llvm.org/D52091
|
|
|
|
|
2019-09-21 17:26:53 +03:00
|
|
|
** Update for clang 9 ** : After some backouts, this patch eventually landed
|
|
|
|
upstream in a different form, as the TLS handler `asan_thread_exit`, but that
|
|
|
|
variant causes failures in our test suite, so revert the TLS handler in favor of
|
|
|
|
the interceptor approach from the first patch.
|
|
|
|
|
2020-05-20 08:29:18 +03:00
|
|
|
--- a/compiler-rt/lib/asan/asan_win.cc
|
|
|
|
+++ b/compiler-rt/lib/asan/asan_win.cc
|
|
|
|
@@ -154,6 +154,14 @@
|
2019-09-21 17:26:53 +03:00
|
|
|
thr_flags, tid);
|
2019-03-09 23:34:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
+INTERCEPTOR_WINAPI(void, NtTerminateThread, void *rcx) {
|
|
|
|
+ // Unpoison the terminating thread's stack because the memory may be re-used.
|
|
|
|
+ NT_TIB *tib = (NT_TIB *)NtCurrentTeb();
|
|
|
|
+ uptr stackSize = (uptr)tib->StackBase - (uptr)tib->StackLimit;
|
|
|
|
+ __asan_unpoison_memory_region(tib->StackLimit, stackSize);
|
|
|
|
+ return REAL(NtTerminateThread(rcx));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
// }}}
|
|
|
|
|
|
|
|
namespace __asan {
|
2020-05-20 08:29:18 +03:00
|
|
|
@@ -168,7 +176,9 @@
|
2019-03-09 23:34:50 +03:00
|
|
|
|
|
|
|
ASAN_INTERCEPT_FUNC(CreateThread);
|
|
|
|
ASAN_INTERCEPT_FUNC(SetUnhandledExceptionFilter);
|
|
|
|
-
|
|
|
|
+ CHECK(::__interception::OverrideFunction("NtTerminateThread",
|
|
|
|
+ (uptr)WRAP(NtTerminateThread),
|
|
|
|
+ (uptr *)&REAL(NtTerminateThread)));
|
|
|
|
#ifdef _WIN64
|
|
|
|
ASAN_INTERCEPT_FUNC(__C_specific_handler);
|
|
|
|
#else
|
2020-05-20 08:29:18 +03:00
|
|
|
@@ -380,19 +390,6 @@
|
2019-09-21 17:26:53 +03:00
|
|
|
void *, unsigned long, void *) = asan_thread_init;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
-static void NTAPI asan_thread_exit(void *module, DWORD reason, void *reserved) {
|
|
|
|
- if (reason == DLL_THREAD_DETACH) {
|
|
|
|
- // Unpoison the thread's stack because the memory may be re-used.
|
|
|
|
- NT_TIB *tib = (NT_TIB *)NtCurrentTeb();
|
|
|
|
- uptr stackSize = (uptr)tib->StackBase - (uptr)tib->StackLimit;
|
|
|
|
- __asan_unpoison_memory_region(tib->StackLimit, stackSize);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
2020-05-20 08:29:18 +03:00
|
|
|
-#pragma section(".CRT$XLY", long, read) // NOLINT
|
2019-09-21 17:26:53 +03:00
|
|
|
-__declspec(allocate(".CRT$XLY")) void(NTAPI *__asan_tls_exit)(
|
|
|
|
- void *, unsigned long, void *) = asan_thread_exit;
|
|
|
|
-
|
|
|
|
WIN_FORCE_LINK(__asan_dso_reg_hook)
|
|
|
|
|
|
|
|
// }}}
|