From 9cba2e2d97e88633bf5a42ec2f73121f0a72a8d4 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Fri, 5 Aug 2016 21:47:46 +0000 Subject: [PATCH] Fix two tests in Win64 ASan Go back to intercepting kernel32!RaiseException, and only go for ntdll!RtlRaiseException if that fails. Fixes throw_and_catch.cc test. Work around an issue in LLVM's win64 epilogues. We end up with an epilogue that looks like this, and it drives the Win64 unwinder crazy until stack overflow: call ill_cc!__asan_handle_no_return xor eax,eax add rsp,40h // epilogue starts pop rbp // CSR ud2 // Trap here ret // Ret? nop word ptr [rax+rax] sub rsp,28h // Next function Will file a PR soon. llvm-svn: 277874 --- compiler-rt/lib/asan/asan_win.cc | 19 +++++++++++++++---- compiler-rt/test/asan/TestCases/Windows/dll_host.cc | 1 + compiler-rt/test/asan/TestCases/ill.cc | 7 +++++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/compiler-rt/lib/asan/asan_win.cc b/compiler-rt/lib/asan/asan_win.cc index 97a913e..0616e40 100644 --- a/compiler-rt/lib/asan/asan_win.cc +++ b/compiler-rt/lib/asan/asan_win.cc @@ -80,6 +80,11 @@ INTERCEPTOR_WINAPI(void, RtlRaiseException, EXCEPTION_RECORD *ExceptionRecord) { REAL(RtlRaiseException)(ExceptionRecord); } +INTERCEPTOR_WINAPI(void, RaiseException, void *a, void *b, void *c, void *d) { + CHECK(REAL(RaiseException)); + __asan_handle_no_return(); + REAL(RaiseException)(a, b, c, d); +} #ifdef _WIN64 @@ -138,10 +143,6 @@ namespace __asan { void InitializePlatformInterceptors() { ASAN_INTERCEPT_FUNC(CreateThread); - // RtlRaiseException is always linked dynamically. - CHECK(::__interception::OverrideFunction("RtlRaiseException", - (uptr)WRAP(RtlRaiseException), - (uptr *)&REAL(RtlRaiseException))); #ifdef _WIN64 ASAN_INTERCEPT_FUNC(__C_specific_handler); @@ -149,6 +150,16 @@ void InitializePlatformInterceptors() { ASAN_INTERCEPT_FUNC(_except_handler3); ASAN_INTERCEPT_FUNC(_except_handler4); #endif + + // Try to intercept kernel32!RaiseException, and if that fails, intercept + // ntdll!RtlRaiseException instead. + if (!::__interception::OverrideFunction("RaiseException", + (uptr)WRAP(RaiseException), + (uptr *)&REAL(RaiseException))) { + CHECK(::__interception::OverrideFunction("RtlRaiseException", + (uptr)WRAP(RtlRaiseException), + (uptr *)&REAL(RtlRaiseException))); + } } void AsanApplyToGlobals(globals_op_fptr op, const void *needle) { diff --git a/compiler-rt/test/asan/TestCases/Windows/dll_host.cc b/compiler-rt/test/asan/TestCases/Windows/dll_host.cc index 7209460..6a029c9 100644 --- a/compiler-rt/test/asan/TestCases/Windows/dll_host.cc +++ b/compiler-rt/test/asan/TestCases/Windows/dll_host.cc @@ -24,6 +24,7 @@ // IMPORT: __asan_wrap_HeapReAlloc // IMPORT: __asan_wrap_HeapSize // IMPORT: __asan_wrap_CreateThread +// IMPORT: __asan_wrap_RaiseException // IMPORT: __asan_wrap_RtlRaiseException // // The exception handlers differ in 32-bit and 64-bit, so we ignore them: diff --git a/compiler-rt/test/asan/TestCases/ill.cc b/compiler-rt/test/asan/TestCases/ill.cc index fae837c..cad1584 100644 --- a/compiler-rt/test/asan/TestCases/ill.cc +++ b/compiler-rt/test/asan/TestCases/ill.cc @@ -9,7 +9,7 @@ #include #endif -int main() { +int main(int argc, char **argv) { #ifdef _WIN32 // Sometimes on Windows this test generates a WER fault dialog. Suppress that. UINT new_flags = SEM_FAILCRITICALERRORS | @@ -21,7 +21,10 @@ int main() { SetErrorMode(existing_flags | new_flags); #endif - __builtin_trap(); + if (argc) + __builtin_trap(); + // Unreachable code to avoid confusing the Windows unwinder. + SetErrorMode(0); } // CHECK0-NOT: ERROR: AddressSanitizer // CHECK1: ERROR: AddressSanitizer: {{ILL|illegal-instruction}} on unknown address {{0x0*}} -- 2.7.4