summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_win.cc13
-rw-r--r--compiler-rt/test/asan/TestCases/Windows/crash_read_write.cc29
-rw-r--r--compiler-rt/test/asan/TestCases/Windows/report_after_syminitialize.cc4
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.
}
OpenPOWER on IntegriCloud