Index: lib/asan/asan_errors.cc =================================================================== --- lib/asan/asan_errors.cc +++ lib/asan/asan_errors.cc @@ -32,7 +32,15 @@ Printf("%s", d.EndWarning()); scariness.Print(); BufferedStackTrace stack; - GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, context, + uptr adjusted_pc = pc; +#if SANITIZER_LINUX && !defined(__arm__) + // Undo the damage StackTrace::GetPreviousInstructionPc will do to the pc. + // For deadly signal pc we have here is actually the pc of the faulting + // instruction. + adjusted_pc += pc - StackTrace::GetPreviousInstructionPc (pc); +#endif + GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, adjusted_pc, bp, + context, common_flags()->fast_unwind_on_fatal); stack.Print(); ReportErrorSummary(scariness.GetDescription(), &stack); @@ -79,8 +87,15 @@ } scariness.Print(); BufferedStackTrace stack; - GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, context, - common_flags()->fast_unwind_on_fatal); + uptr adjusted_pc = pc; +#if SANITIZER_LINUX && !defined(__arm__) + // Undo the damage StackTrace::GetPreviousInstructionPc will do to the pc. + // For deadly signal pc we have here is actually the pc of the faulting + // instruction. + adjusted_pc += pc - StackTrace::GetPreviousInstructionPc (pc); +#endif + GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, adjusted_pc, bp, + context, common_flags()->fast_unwind_on_fatal); stack.Print(); MaybeDumpInstructionBytes(pc); MaybeDumpRegisters(context); Index: lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc +++ lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc @@ -94,6 +94,17 @@ 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 (ctx, &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