[Windows] Fill in read/write information in SignalContext

Implements https://github.com/google/sanitizers/issues/653

llvm-svn: 260539
This commit is contained in:
Reid Kleckner 2016-02-11 16:44:35 +00:00
parent 75fab7b0b0
commit ceda883e4d
3 changed files with 43 additions and 3 deletions

View File

@ -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);
}

View File

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

View File

@ -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.
}