diff options
author | Yao Qi <yao.qi@arm.com> | 2016-05-23 17:32:56 +0100 |
---|---|---|
committer | Yao Qi <yao.qi@linaro.org> | 2016-05-23 17:32:56 +0100 |
commit | 7eb895307f53af3435440d3fe67c0e4e679d99b2 (patch) | |
tree | f00e0024cc8dbc112a7c99c5b604e0a7dd9501ab /gdb/gdbarch.h | |
parent | 0f6ed0e0efe2c4dcd35b0e483dc3b5da7fe4edf0 (diff) | |
download | gdb-7eb895307f53af3435440d3fe67c0e4e679d99b2.zip gdb-7eb895307f53af3435440d3fe67c0e4e679d99b2.tar.gz gdb-7eb895307f53af3435440d3fe67c0e4e679d99b2.tar.bz2 |
Skip unwritable frames in command "finish"
Nowadays, GDB can't insert breakpoint on the return address of the
exception handler on ARM M-profile, because the address is a magic
one 0xfffffff9,
(gdb) bt
#0 CT32B1_IRQHandler () at ../src/timer.c:67
#1 <signal handler called>
#2 main () at ../src/timer.c:127
(gdb) info frame
Stack level 0, frame at 0x200ffa8:
pc = 0x4ec in CT32B1_IRQHandler (../src/timer.c:67); saved pc = 0xfffffff9
called by frame at 0x200ffc8
source language c.
Arglist at 0x200ffa0, args:
Locals at 0x200ffa0, Previous frame's sp is 0x200ffa8
Saved registers:
r7 at 0x200ffa0, lr at 0x200ffa4
(gdb) x/x 0xfffffff9
0xfffffff9: Cannot access memory at address 0xfffffff9
(gdb) finish
Run till exit from #0 CT32B1_IRQHandler () at ../src/timer.c:67
Ed:15: Target error from Set break/watch: Et:96: Pseudo-address (0xFFFFFFxx) for EXC_RETURN is invalid (GDB error?)
Warning:
Cannot insert hardware breakpoint 0.
Could not insert hardware breakpoints:
You may have requested too many hardware breakpoints/watchpoints.
Command aborted.
even some debug probe can't set hardware breakpoint on the magic
address too,
(gdb) hbreak *0xfffffff9
Hardware assisted breakpoint 2 at 0xfffffff9
(gdb) c
Continuing.
Ed:15: Target error from Set break/watch: Et:96: Pseudo-address (0xFFFFFFxx) for EXC_RETURN is invalid (GDB error?)
Warning:
Cannot insert hardware breakpoint 2.
Could not insert hardware breakpoints:
You may have requested too many hardware breakpoints/watchpoints.
Command aborted.
The problem described above is quite similar to PR 8841, in which GDB
can't set breakpoint on signal trampoline, which is mapped to a read-only
page by kernel. The rationale of this patch is to skip "unwritable"
frames when looking for caller frames in command "finish", and a new
gdbarch method code_of_frame_writable is added. This patch fixes
the problem on ARM cortex-m target, but it can be used to fix
PR 8841 too.
gdb:
2016-05-10 Yao Qi <yao.qi@arm.com>
* arch-utils.c (default_code_of_frame_writable): New function.
* arch-utils.h (default_code_of_frame_writable): Declare.
* arm-tdep.c (arm_code_of_frame_writable): New function.
(arm_gdbarch_init): Install gdbarch method
code_of_frame_writable if the target is M-profile.
* frame.c (skip_unwritable_frames): New function.
* frame.h (skip_unwritable_frames): Declare.
* gdbarch.sh (code_of_frame_writable): New.
* gdbarch.c, gdbarch.h: Re-generated.
* infcmd.c (finish_command): Call skip_unwritable_frames.
Diffstat (limited to 'gdb/gdbarch.h')
-rw-r--r-- | gdb/gdbarch.h | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 859ba85..a6366fc 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -395,6 +395,12 @@ typedef CORE_ADDR (gdbarch_push_dummy_code_ftype) (struct gdbarch *gdbarch, CORE extern CORE_ADDR gdbarch_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp, CORE_ADDR funaddr, struct value **args, int nargs, struct type *value_type, CORE_ADDR *real_pc, CORE_ADDR *bp_addr, struct regcache *regcache); extern void set_gdbarch_push_dummy_code (struct gdbarch *gdbarch, gdbarch_push_dummy_code_ftype *push_dummy_code); +/* Return true if the code of FRAME is writable. */ + +typedef int (gdbarch_code_of_frame_writable_ftype) (struct gdbarch *gdbarch, struct frame_info *frame); +extern int gdbarch_code_of_frame_writable (struct gdbarch *gdbarch, struct frame_info *frame); +extern void set_gdbarch_code_of_frame_writable (struct gdbarch *gdbarch, gdbarch_code_of_frame_writable_ftype *code_of_frame_writable); + typedef void (gdbarch_print_registers_info_ftype) (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, int regnum, int all); extern void gdbarch_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, int regnum, int all); extern void set_gdbarch_print_registers_info (struct gdbarch *gdbarch, gdbarch_print_registers_info_ftype *print_registers_info); |