summaryrefslogtreecommitdiffstats
path: root/build/build-clang/unpoison-thread-stacks.patch
blob: 2fb7cafd90494455baac3eff196f5f5ecc134caf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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)
 
 // }}}