summaryrefslogtreecommitdiffstats
path: root/build/build-clang/unpoison-thread-stacks.patch
diff options
context:
space:
mode:
Diffstat (limited to 'build/build-clang/unpoison-thread-stacks.patch')
-rw-r--r--build/build-clang/unpoison-thread-stacks.patch62
1 files changed, 62 insertions, 0 deletions
diff --git a/build/build-clang/unpoison-thread-stacks.patch b/build/build-clang/unpoison-thread-stacks.patch
new file mode 100644
index 0000000000..2fb7cafd90
--- /dev/null
+++ b/build/build-clang/unpoison-thread-stacks.patch
@@ -0,0 +1,62 @@
+[winasan] Unpoison the stack in NtTerminateThread
+
+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.
+
+Differential Revision: https://reviews.llvm.org/D52091
+
+** 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.
+
+--- a/compiler-rt/lib/asan/asan_win.cc
++++ b/compiler-rt/lib/asan/asan_win.cc
+@@ -154,6 +154,14 @@
+ thr_flags, tid);
+ }
+
++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 {
+@@ -168,7 +176,9 @@
+
+ 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
+@@ -380,19 +390,6 @@
+ 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);
+- }
+-}
+-
+-#pragma section(".CRT$XLY", long, read) // NOLINT
+-__declspec(allocate(".CRT$XLY")) void(NTAPI *__asan_tls_exit)(
+- void *, unsigned long, void *) = asan_thread_exit;
+-
+ WIN_FORCE_LINK(__asan_dso_reg_hook)
+
+ // }}}