https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79341
--- Comment #64 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Perhaps the easiest hack would be for sanitizer_common/sanitizer_unwind_linux_libcdep.cc (Unwind_GetIP) call _Unwind_GetIPInfo instead of _Unwind_GetIP (perhaps just on SANITIZER_LINUX or wherever it is available), and return for the signal frames the pc + 1 so that the later - 1 subtraction undoes that. So like (completely untested, but I also can't reproduce the nullptr-1.c failure myself): --- libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cc.jj 2016-11-09 15:22:41.000000000 +0100 +++ libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cc 2017-02-15 15:26:31.658948328 +0100 @@ -92,6 +92,17 @@ uptr Unwind_GetIP(struct _Unwind_Context CHECK(res == _UVRSR_OK && "_Unwind_VRS_Get failed"); // Clear the Thumb bit. return val & ~(uptr)1; +#elif SANITIZER_LINUX && !defined(__arm__) + int pc_before_insn = 0; + uptr pc = _Unwind_GetIPInfo (context, &pc_before_insn); + /* If context is for a signal frame, the returned PC is + the right one to use, but StackTrace::GetPreviousInstructionPc + will be applied to it later unconditionally. So adjust PC now + so that GetPreviousInstructionPc will return what _Unwind_GetIPInfo + returned. */ + if (pc_before_insn) + pc += pc - StackTrace::GetPreviousInstructionPc (pc); + return pc; #else return _Unwind_GetIP(ctx); #endif