aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/arm-tdep.c43
2 files changed, 32 insertions, 16 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 437dbc2..5655ccb 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
2015-11-23 Joel Brobecker <brobecker@adacore.com>
+ * arm-tdep.c (arm_exidx_unwind_sniffer): Do not check for a frame
+ stuck on a system call if the given frame is the innermost frame.
+
+2015-11-23 Joel Brobecker <brobecker@adacore.com>
+
* dwarf2read.c (read_structure_type): Set the type's length
to zero if it has a DW_AT_byte_size attribute which is not
a constant.
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index ef1a007..6ce6f09c 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -2814,26 +2814,37 @@ arm_exidx_unwind_sniffer (const struct frame_unwind *self,
/* We also assume exception information is valid if we're currently
blocked in a system call. The system library is supposed to
- ensure this, so that e.g. pthread cancellation works. */
- if (arm_frame_is_thumb (this_frame))
- {
- LONGEST insn;
+ ensure this, so that e.g. pthread cancellation works.
- if (safe_read_memory_integer (get_frame_pc (this_frame) - 2, 2,
- byte_order_for_code, &insn)
- && (insn & 0xff00) == 0xdf00 /* svc */)
- exc_valid = 1;
- }
- else
+ But before verifying the instruction at the point of call, make
+ sure this_frame is actually making a call (or, said differently,
+ that it is not the innermost frame). For that, we compare
+ this_frame's PC vs this_frame's addr_in_block. If equal, it means
+ there is no call (otherwise, the PC would be the return address,
+ which is the instruction after the call). */
+
+ if (get_frame_pc (this_frame) != addr_in_block)
{
- LONGEST insn;
+ if (arm_frame_is_thumb (this_frame))
+ {
+ LONGEST insn;
- if (safe_read_memory_integer (get_frame_pc (this_frame) - 4, 4,
- byte_order_for_code, &insn)
- && (insn & 0x0f000000) == 0x0f000000 /* svc */)
- exc_valid = 1;
+ if (safe_read_memory_integer (get_frame_pc (this_frame) - 2, 2,
+ byte_order_for_code, &insn)
+ && (insn & 0xff00) == 0xdf00 /* svc */)
+ exc_valid = 1;
+ }
+ else
+ {
+ LONGEST insn;
+
+ if (safe_read_memory_integer (get_frame_pc (this_frame) - 4, 4,
+ byte_order_for_code, &insn)
+ && (insn & 0x0f000000) == 0x0f000000 /* svc */)
+ exc_valid = 1;
+ }
}
-
+
/* Bail out if we don't know that exception information is valid. */
if (!exc_valid)
return 0;