Index: compiler-rt/lib/asan/asan_errors.h =================================================================== --- compiler-rt/lib/asan/asan_errors.h +++ compiler-rt/lib/asan/asan_errors.h @@ -57,14 +57,14 @@ // VS2013 doesn't implement unrestricted unions, so we need a trivial default // constructor ErrorDeadlySignal() = default; - ErrorDeadlySignal(u32 tid, const SignalContext &sig, int signo_) + ErrorDeadlySignal(u32 tid, const SignalContext &sig) : ErrorBase(tid), addr(sig.addr), pc(sig.pc), bp(sig.bp), sp(sig.sp), context(sig.context), - signo(signo_), + signo(sig.GetType()), write_flag(sig.write_flag), is_memory_access(sig.is_memory_access) { scariness.Clear(); Index: compiler-rt/lib/asan/asan_posix.cc =================================================================== --- compiler-rt/lib/asan/asan_posix.cc +++ compiler-rt/lib/asan/asan_posix.cc @@ -37,10 +37,10 @@ ScopedDeadlySignal signal_scope(GetCurrentThread()); StartReportDeadlySignal(); SignalContext sig = SignalContext::Create(siginfo, context); - if (IsStackOverflow(((siginfo_t *)siginfo)->si_code, sig)) + if (IsStackOverflow(sig)) ReportStackOverflow(sig); else - ReportDeadlySignal(signo, sig); + ReportDeadlySignal(sig); } // ---------------------- TSD ---------------- {{{1 Index: compiler-rt/lib/asan/asan_report.h =================================================================== --- compiler-rt/lib/asan/asan_report.h +++ compiler-rt/lib/asan/asan_report.h @@ -47,7 +47,7 @@ void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write, uptr access_size, u32 exp, bool fatal); void ReportStackOverflow(const SignalContext &sig); -void ReportDeadlySignal(int signo, const SignalContext &sig); +void ReportDeadlySignal(const SignalContext &sig); void ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size, BufferedStackTrace *free_stack); void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack); Index: compiler-rt/lib/asan/asan_report.cc =================================================================== --- compiler-rt/lib/asan/asan_report.cc +++ compiler-rt/lib/asan/asan_report.cc @@ -266,9 +266,9 @@ in_report.ReportError(error); } -void ReportDeadlySignal(int signo, const SignalContext &sig) { +void ReportDeadlySignal(const SignalContext &sig) { ScopedInErrorReport in_report(/*fatal*/ true); - ErrorDeadlySignal error(GetCurrentTidOrInvalid(), sig, signo); + ErrorDeadlySignal error(GetCurrentTidOrInvalid(), sig); in_report.ReportError(error); } 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 @@ -312,7 +312,7 @@ const char *DescribeSignalOrException(int signo); // Signal reporting. void StartReportDeadlySignal(); -bool IsStackOverflow(int code, const SignalContext &sig); +bool IsStackOverflow(const SignalContext &sig); // FIXME: Hide after moving more signal handling code into common. void MaybeReportNonExecRegion(uptr pc); void MaybeDumpInstructionBytes(uptr pc); @@ -795,6 +795,7 @@ } struct SignalContext { + void *siginfo; void *context; uptr addr; uptr pc; @@ -804,9 +805,12 @@ enum WriteFlag { UNKNOWN, READ, WRITE } write_flag; - SignalContext(void *context, uptr addr, uptr pc, uptr sp, uptr bp, - bool is_memory_access, WriteFlag write_flag) - : context(context), + // SignalContext is going to keep pointers to siginfo and context without + // owning them. + SignalContext(void *siginfo, void *context, uptr addr, uptr pc, uptr sp, + uptr bp, bool is_memory_access, WriteFlag write_flag) + : siginfo(siginfo), + context(context), addr(addr), pc(pc), sp(sp), @@ -821,6 +825,12 @@ // Returns true if the "context" indicates a memory write. static WriteFlag GetWriteFlag(void *context); + + // Type of signal e.g. SIGSEGV or EXCEPTION_ACCESS_VIOLATION. + int GetType() const; + + // String description of the signal. + const char *Describe() const { return DescribeSignalOrException(GetType()); } }; void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp); 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 @@ -296,13 +296,18 @@ } SignalContext SignalContext::Create(void *siginfo, void *context) { - auto si = (siginfo_t *)siginfo; + auto si = static_cast(siginfo); uptr addr = (uptr)si->si_addr; uptr pc, sp, bp; GetPcSpBp(context, &pc, &sp, &bp); WriteFlag write_flag = GetWriteFlag(context); bool is_memory_access = si->si_signo == SIGSEGV; - return SignalContext(context, addr, pc, sp, bp, is_memory_access, write_flag); + return SignalContext(siginfo, context, addr, pc, sp, bp, is_memory_access, + write_flag); +} + +int SignalContext::GetType() const { + return static_cast(siginfo)->si_signo; } const char *DescribeSignalOrException(int signo) { Index: compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc +++ compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc @@ -215,7 +215,7 @@ MaybeInstallSigaction(SIGILL, handler); } -bool IsStackOverflow(int code, const SignalContext &sig) { +bool IsStackOverflow(const SignalContext &sig) { // Access at a reasonable offset above SP, or slightly below it (to account // for x86_64 or PowerPC redzone, ARM push of multiple registers, etc) is // probably a stack overflow. @@ -257,7 +257,9 @@ // We also check si_code to filter out SEGV caused by something else other // then hitting the guard page or unmapped memory, like, for example, // unaligned memory access. - return IsStackAccess && (code == si_SEGV_MAPERR || code == si_SEGV_ACCERR); + auto si = static_cast(sig.siginfo); + return IsStackAccess && + (si->si_code == si_SEGV_MAPERR || si->si_code == si_SEGV_ACCERR); } void StartReportDeadlySignal() { 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 @@ -966,14 +966,18 @@ 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); + return SignalContext(siginfo, context, access_addr, pc, sp, bp, + is_memory_access, write_flag); } void SignalContext::DumpAllRegisters(void *context) { // FIXME: Implement this. } +int SignalContext::GetType() const { + return static_cast(siginfo)->ExceptionCode; +} + uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { // FIXME: Actually implement this function. CHECK_GT(buf_len, 0);