--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -1,3 +1,15 @@
+2015-04-19 Martin Sebor <mse...@redhat.com>
+
+ PR sanitizer/65479
+ * libsanitizer/sanitizer_common/sanitizer_stacktrace.h
+ (StackTrace::signaled, StackTrace::min_insn_bytes): New data members.
+ (StackTrace::StackTrace): Initialize signaled.
+ * libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
+ (StackTrace::GetPreviousInstructionPc): Rewrite.
+ * libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cc
+ (StackTrace::Print): Use min_insn_bytes to adjust PC value.
+ (BufferedStackTrace::Unwind): Set signaled.
libsanitizer/ should not show up in the ChangeLog entry.
But as somebody said earlier, the libsanitizer changes really should go
to LLVM compiler-rt repo first and then be just backported, either
cherry-picked (probably the case for the 5 branch backport later on) or go in
full merge from compiler-rt.
Okay, let me submit the sanitizer changes there. Since the
tests will continue to fail without it, the libbacktrace
change can go in later if that's preferable.
--- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
@@ -15,19 +15,33 @@
namespace __sanitizer {
-uptr StackTrace::GetPreviousInstructionPc(uptr pc) {
-#if defined(__arm__)
- // Cancel Thumb bit.
- pc = pc & (~1);
-#endif
Your code loses this, which is undesirable.
The original function fails to return the pc value on ARM
so I just took it out. I didn't look into what the intent
was but all the tests pass with the patch on aarch64 (after
applying the Fedora gcc 5 patch you mentioned yesterday).
-#if defined(__powerpc__) || defined(__powerpc64__)
- // PCs are always 4 byte aligned.
- return pc - 4;
-#elif defined(__sparc__) || defined(__mips__)
- return pc - 8;
The SPARC/MIPS case is of course needed, because on these architectures
the call is followed by a delay slot. But I wonder why you need anything
special on any other architecture, why pc - 1 isn't good enough for those.
The point isn't to find a PC of the call instruction, on some targets that
is very hard and you need to disassemble, but to just find some byte in the
call instruction.
I forgot about the delay slot. Thanks for the reminder.
+const unsigned StackTrace::min_insn_bytes =
+#if defined __ia64__
+ // Intel Itanium has 5 byte instructions.
+ 5
E.g. this is wrong, ia64 doesn't have 5 byte instructions, but has VLIW
bundles, where in the 16 byte bundle there are up to 3 41-bit instructions
plus template. But, ia64 isn't supported by libsanitizer and I doubt there
are enough users that would be interested in writing support for a dead
architecture.
I suppose with the sanitizer output referencing the unmodified
PC values on the stack the computation can be simplified to
just subtract (and later add) 1 on all targets. Let me change
that.
Martin