diff options
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/arm-tdep.c | 43 |
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; |