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
This commit is contained in:
Reid Kleckner
2016-08-05 21:47:46 +00:00
parent 7af95876cf
commit 9cba2e2d97
3 changed files with 21 additions and 6 deletions

View File

@@ -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) {

View File

@@ -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:

View File

@@ -9,7 +9,7 @@
#include <windows.h>
#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*}}