diff options
3 files changed, 43 insertions, 3 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cc b/compiler-rt/lib/sanitizer_common/sanitizer_win.cc index 18fd0180178..4a6dc34cffd 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cc @@ -744,8 +744,17 @@ SignalContext SignalContext::Create(void *siginfo, void *context) { #endif uptr access_addr = exception_record->ExceptionInformation[1]; - WriteFlag write_flag = SignalContext::UNKNOWN; // FIXME: compute this. - bool is_memory_access = false; // FIXME: compute this. + // The contents of this array are documented at + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa363082(v=vs.85).aspx + // The first element indicates read as 0, write as 1, or execute as 8. The + // second element is the faulting address. + WriteFlag write_flag = SignalContext::UNKNOWN; + switch (exception_record->ExceptionInformation[0]) { + case 0: write_flag = SignalContext::READ; break; + case 1: write_flag = SignalContext::WRITE; break; + case 8: write_flag = SignalContext::UNKNOWN; break; + } + bool is_memory_access = write_flag != SignalContext::UNKNOWN; return SignalContext(context, access_addr, pc, sp, bp, is_memory_access, write_flag); } diff --git a/compiler-rt/test/asan/TestCases/Windows/crash_read_write.cc b/compiler-rt/test/asan/TestCases/Windows/crash_read_write.cc new file mode 100644 index 00000000000..74200cca152 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/Windows/crash_read_write.cc @@ -0,0 +1,29 @@ +// RUN: %clangxx_asan -std=c++11 -O0 %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=READ +// RUN: not %run %t write 2>&1 | FileCheck %s --check-prefix=WRITE + +#include <windows.h> +#include <stdio.h> + +static volatile int sink; +__attribute__((noinline)) void Read(int *ptr) { sink = *ptr; } +__attribute__((noinline)) void Write(int *ptr) { *ptr = 0; } +int main(int argc, char **argv) { + // Writes to shadow are detected as reads from shadow gap (because of how the + // shadow mapping works). This is kinda hard to fix. Test a random address in + // the application part of the address space. + void *volatile p = VirtualAlloc(0, 4096, MEM_COMMIT, PAGE_READONLY); + bool ok = VirtualFree(p, 0, MEM_RELEASE); + if (!ok) { + printf("VirtualFree failed\n"); + return 0; + } + if (argc == 1) + Read((int *)p); + else + Write((int *)p); +} +// READ: AddressSanitizer: access-violation on unknown address +// READ: The signal is caused by a READ memory access. +// WRITE: AddressSanitizer: access-violation on unknown address +// WRITE: The signal is caused by a WRITE memory access. diff --git a/compiler-rt/test/asan/TestCases/Windows/report_after_syminitialize.cc b/compiler-rt/test/asan/TestCases/Windows/report_after_syminitialize.cc index d83d7dc264a..20bf6951417 100644 --- a/compiler-rt/test/asan/TestCases/Windows/report_after_syminitialize.cc +++ b/compiler-rt/test/asan/TestCases/Windows/report_after_syminitialize.cc @@ -14,8 +14,10 @@ int main() { *(volatile int*)0 = 42; // CHECK: ERROR: AddressSanitizer: access-violation on unknown address + // CHECK: The signal is caused by a WRITE memory access. + // CHECK: Hint: address points to the zero page. // CHECK-NEXT: {{WARNING: Failed to use and restart external symbolizer}} // CHECK-NEXT: {{WARNING: .*DbgHelp}} - // CHECK: {{#0 0x.* in main.*report_after_syminitialize.cc:}}[[@LINE-4]] + // CHECK: {{#0 0x.* in main.*report_after_syminitialize.cc:}}[[@LINE-6]] // CHECK: AddressSanitizer can not provide additional info. } |

