Index: compiler-rt/lib/asan/asan_errors.h =================================================================== --- compiler-rt/lib/asan/asan_errors.h +++ compiler-rt/lib/asan/asan_errors.h @@ -28,19 +28,12 @@ }; struct ErrorStackOverflow : ErrorBase { - uptr addr, pc, bp, sp; - // ErrorStackOverflow never owns the context. - void *context; + SignalContext sig; // VS2013 doesn't implement unrestricted unions, so we need a trivial default // constructor ErrorStackOverflow() = default; ErrorStackOverflow(u32 tid, const SignalContext &sig) - : ErrorBase(tid), - addr(sig.addr), - pc(sig.pc), - bp(sig.bp), - sp(sig.sp), - context(sig.context) { + : ErrorBase(tid), sig(sig) { scariness.Clear(); scariness.Scare(10, "stack-overflow"); } @@ -48,34 +41,21 @@ }; struct ErrorDeadlySignal : ErrorBase { - uptr addr, pc, bp, sp; - // ErrorDeadlySignal never owns the context. - void *context; - int signo; - SignalContext::WriteFlag write_flag; - bool is_memory_access; + SignalContext sig; // VS2013 doesn't implement unrestricted unions, so we need a trivial default // constructor ErrorDeadlySignal() = default; ErrorDeadlySignal(u32 tid, const SignalContext &sig) - : ErrorBase(tid), - addr(sig.addr), - pc(sig.pc), - bp(sig.bp), - sp(sig.sp), - context(sig.context), - signo(sig.Get()), - write_flag(sig.write_flag), - is_memory_access(sig.is_memory_access) { + : ErrorBase(tid), sig(sig) { scariness.Clear(); - if (is_memory_access) { - if (addr < GetPageSizeCached()) { + if (sig.is_memory_access) { + if (sig.addr < GetPageSizeCached()) { scariness.Scare(10, "null-deref"); - } else if (addr == pc) { + } else if (sig.addr == sig.pc) { scariness.Scare(60, "wild-jump"); - } else if (write_flag == SignalContext::WRITE) { + } else if (sig.write_flag == SignalContext::WRITE) { scariness.Scare(30, "wild-addr-write"); - } else if (write_flag == SignalContext::READ) { + } else if (sig.write_flag == SignalContext::READ) { scariness.Scare(20, "wild-addr-read"); } else { scariness.Scare(25, "wild-addr"); Index: compiler-rt/lib/asan/asan_errors.cc =================================================================== --- compiler-rt/lib/asan/asan_errors.cc +++ compiler-rt/lib/asan/asan_errors.cc @@ -27,12 +27,14 @@ Printf("%s", d.Warning()); Report( "ERROR: AddressSanitizer: %s on address %p" - " (pc %p bp %p sp %p T%d)\n", scariness.GetDescription(), - (void *)addr, (void *)pc, (void *)bp, (void *)sp, tid); + " (pc %p bp %p sp %p T%d)\n", + scariness.GetDescription(), (void *)sig.addr, (void *)sig.pc, + (void *)sig.bp, (void *)sig.sp, tid); Printf("%s", d.Default()); scariness.Print(); BufferedStackTrace stack; - GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, context, + GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, sig.pc, sig.bp, + sig.context, common_flags()->fast_unwind_on_fatal); stack.Print(); ReportErrorSummary(scariness.GetDescription(), &stack); @@ -41,30 +43,33 @@ void ErrorDeadlySignal::Print() { Decorator d; Printf("%s", d.Warning()); - const char *description = __sanitizer::DescribeSignalOrException(signo); + const char *description = sig.Describe(); Report( "ERROR: AddressSanitizer: %s on unknown address %p (pc %p bp %p sp %p " "T%d)\n", - description, (void *)addr, (void *)pc, (void *)bp, (void *)sp, tid); + description, (void *)sig.addr, (void *)sig.pc, (void *)sig.bp, + (void *)sig.sp, tid); Printf("%s", d.Default()); - if (pc < GetPageSizeCached()) Report("Hint: pc points to the zero page.\n"); - if (is_memory_access) { + if (sig.pc < GetPageSizeCached()) + Report("Hint: pc points to the zero page.\n"); + if (sig.is_memory_access) { const char *access_type = - write_flag == SignalContext::WRITE + sig.write_flag == SignalContext::WRITE ? "WRITE" - : (write_flag == SignalContext::READ ? "READ" : "UNKNOWN"); + : (sig.write_flag == SignalContext::READ ? "READ" : "UNKNOWN"); Report("The signal is caused by a %s memory access.\n", access_type); - if (addr < GetPageSizeCached()) + if (sig.addr < GetPageSizeCached()) Report("Hint: address points to the zero page.\n"); } - MaybeReportNonExecRegion(pc); + MaybeReportNonExecRegion(sig.pc); scariness.Print(); BufferedStackTrace stack; - GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, context, + GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, sig.pc, sig.bp, + sig.context, common_flags()->fast_unwind_on_fatal); stack.Print(); - MaybeDumpInstructionBytes(pc); - MaybeDumpRegisters(context); + MaybeDumpInstructionBytes(sig.pc); + MaybeDumpRegisters(sig.context); Printf("AddressSanitizer can not provide additional info.\n"); ReportErrorSummary(description, &stack); } Index: compiler-rt/lib/sanitizer_common/sanitizer_common.h =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -309,7 +309,6 @@ typedef void (*SignalHandlerType)(int, void *, void *); HandleSignalMode GetHandleSignalMode(int signum); void InstallDeadlySignalHandlers(SignalHandlerType handler); -const char *DescribeSignalOrException(int signo); // Signal reporting. void StartReportDeadlySignal(); bool IsStackOverflow(const SignalContext &sig); @@ -828,7 +827,7 @@ int Get() const; // String description of the signal. - const char *Describe() const { return DescribeSignalOrException(Get()); } + const char *Describe() const; }; void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp); Index: compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cc =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cc +++ compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cc @@ -98,7 +98,7 @@ void PrintModuleMap() {} void SignalContext::DumpAllRegisters(void *context) { UNIMPLEMENTED(); } -const char *DescribeSignalOrException(int signo) { UNIMPLEMENTED(); } +const char *SignalContext::Describe() const { UNIMPLEMENTED(); } struct UnwindTraceArg { BufferedStackTrace *stack; Index: compiler-rt/lib/sanitizer_common/sanitizer_posix.cc =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_posix.cc +++ compiler-rt/lib/sanitizer_common/sanitizer_posix.cc @@ -310,8 +310,8 @@ return static_cast(siginfo)->si_signo; } -const char *DescribeSignalOrException(int signo) { - switch (signo) { +const char *SignalContext::Describe() const { + switch (Get()) { case SIGFPE: return "FPE"; case SIGILL: Index: compiler-rt/lib/sanitizer_common/sanitizer_win.cc =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_win.cc +++ compiler-rt/lib/sanitizer_common/sanitizer_win.cc @@ -890,32 +890,6 @@ return false; } -const char *DescribeSignalOrException(int signo) { - unsigned code = signo; - // Get the string description of the exception if this is a known deadly - // exception. - switch (code) { - case EXCEPTION_ACCESS_VIOLATION: return "access-violation"; - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return "array-bounds-exceeded"; - case EXCEPTION_STACK_OVERFLOW: return "stack-overflow"; - case EXCEPTION_DATATYPE_MISALIGNMENT: return "datatype-misalignment"; - case EXCEPTION_IN_PAGE_ERROR: return "in-page-error"; - case EXCEPTION_ILLEGAL_INSTRUCTION: return "illegal-instruction"; - case EXCEPTION_PRIV_INSTRUCTION: return "priv-instruction"; - case EXCEPTION_BREAKPOINT: return "breakpoint"; - case EXCEPTION_FLT_DENORMAL_OPERAND: return "flt-denormal-operand"; - case EXCEPTION_FLT_DIVIDE_BY_ZERO: return "flt-divide-by-zero"; - case EXCEPTION_FLT_INEXACT_RESULT: return "flt-inexact-result"; - case EXCEPTION_FLT_INVALID_OPERATION: return "flt-invalid-operation"; - case EXCEPTION_FLT_OVERFLOW: return "flt-overflow"; - case EXCEPTION_FLT_STACK_CHECK: return "flt-stack-check"; - case EXCEPTION_FLT_UNDERFLOW: return "flt-underflow"; - case EXCEPTION_INT_DIVIDE_BY_ZERO: return "int-divide-by-zero"; - case EXCEPTION_INT_OVERFLOW: return "int-overflow"; - } - return "unknown exception"; -} - bool IsAccessibleMemoryRange(uptr beg, uptr size) { SYSTEM_INFO si; GetNativeSystemInfo(&si); @@ -978,6 +952,49 @@ return static_cast(siginfo)->ExceptionCode; } +const char *SignalContext::Describe() const { + unsigned code = signo; + // Get the string description of the exception if this is a known deadly + // exception. + switch (code) { + case EXCEPTION_ACCESS_VIOLATION: + return "access-violation"; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + return "array-bounds-exceeded"; + case EXCEPTION_STACK_OVERFLOW: + return "stack-overflow"; + case EXCEPTION_DATATYPE_MISALIGNMENT: + return "datatype-misalignment"; + case EXCEPTION_IN_PAGE_ERROR: + return "in-page-error"; + case EXCEPTION_ILLEGAL_INSTRUCTION: + return "illegal-instruction"; + case EXCEPTION_PRIV_INSTRUCTION: + return "priv-instruction"; + case EXCEPTION_BREAKPOINT: + return "breakpoint"; + case EXCEPTION_FLT_DENORMAL_OPERAND: + return "flt-denormal-operand"; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + return "flt-divide-by-zero"; + case EXCEPTION_FLT_INEXACT_RESULT: + return "flt-inexact-result"; + case EXCEPTION_FLT_INVALID_OPERATION: + return "flt-invalid-operation"; + case EXCEPTION_FLT_OVERFLOW: + return "flt-overflow"; + case EXCEPTION_FLT_STACK_CHECK: + return "flt-stack-check"; + case EXCEPTION_FLT_UNDERFLOW: + return "flt-underflow"; + case EXCEPTION_INT_DIVIDE_BY_ZERO: + return "int-divide-by-zero"; + case EXCEPTION_INT_OVERFLOW: + return "int-overflow"; + } + return "unknown exception"; +} + uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { // FIXME: Actually implement this function. CHECK_GT(buf_len, 0);