https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79341

--- Comment #67 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
This seems to fix the testcase with -march=zEC12 for me.
The problem is that while we carefully compute it, other code than "cleverly"
overwrites it back to the pc it got from the siginfo.

--- sanitizer_common/sanitizer_unwind_linux_libcdep.cc.jj       2017-02-07
11:08:15.000000000 -0500
+++ sanitizer_common/sanitizer_unwind_linux_libcdep.cc  2017-02-15
10:05:13.246850984 -0500
@@ -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 (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
--- asan/asan_errors.cc.jj      2017-02-07 11:08:15.000000000 -0500
+++ asan/asan_errors.cc 2017-02-15 10:56:56.816850984 -0500
@@ -30,7 +30,15 @@ void ErrorStackOverflow::Print() {
   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("stack-overflow", &stack);
@@ -72,8 +80,15 @@ void ErrorDeadlySignal::Print() {
   }
   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);
   Printf("AddressSanitizer can not provide additional info.\n");

Reply via email to