aboutsummaryrefslogtreecommitdiff
path: root/gdb/inline-frame.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2018-06-29 19:31:49 +0100
committerPedro Alves <palves@redhat.com>2018-06-29 19:35:13 +0100
commit991ff2922affa0b3afb837d2246d01f0c1fdb364 (patch)
tree7c6a08537ee9159c4fddfc302bb1dfeed5b1306b /gdb/inline-frame.c
parent356819b6bcc793afea9495243c588da989b4e6e1 (diff)
downloadbinutils-991ff2922affa0b3afb837d2246d01f0c1fdb364.zip
binutils-991ff2922affa0b3afb837d2246d01f0c1fdb364.tar.gz
binutils-991ff2922affa0b3afb837d2246d01f0c1fdb364.tar.bz2
Fix running to breakpoint set in inline function by lineno/address
Commit 61b04dd04ac2 ("Change inline frame breakpoint skipping logic (fix gdb.gdb/selftest.exp)") caused a GDB crash when you set a breakpoint by line number in an inline function, and then run to the breakpoint: $ gdb -q test Reading symbols from test...done. (gdb) b inline-break.c:32 Breakpoint 1 at 0x40062f: file inline-break.c, line 32. (gdb) run Starting program: /[...]/test [1] 75618 segmentation fault /[...]/gdb -q test The problem occurs because we assume that a bp_location's symbol is not NULL, which is not true when we set the breakpoint with a linespec location: Program received signal SIGSEGV, Segmentation fault. 0x00000000006f42bb in stopped_by_user_bp_inline_frame ( stop_chain=<optimized out>, frame_block=<optimized out>) at gdb/inline-frame.c:305 305 && frame_block == SYMBOL_BLOCK_VALUE (loc->symbol)) (gdb) p loc->symbol $1 = (const symbol *) 0x0 The same thing happens if you run to a breakpoint set in an inline function by address: (gdb) b *0x40062f Breakpoint 3 at 0x40062f: file inline-break.c, line 32. To fix this, add a null pointer check, to avoid the crash, and make it so that if there's no symbol for the location, then we present the stop at the inline function. This preserves the previous behavior when e.g., setting a breakpoint by address, with "b *ADDRESS". gdb/ChangeLog: 2018-06-29 Pedro Alves <palves@redhat.com> * inline-frame.c (stopped_by_user_bp_inline_frame): Return true if the the location has no symbol. gdb/testsuite/ChangeLog: 2018-06-29 Pedro Alves <palves@redhat.com> * gdb.opt/inline-break.c (func1): Add "break here" marker. * gdb.opt/inline-break.exp: Test setting breakpoints by line number and address and running to them.
Diffstat (limited to 'gdb/inline-frame.c')
-rw-r--r--gdb/inline-frame.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/gdb/inline-frame.c b/gdb/inline-frame.c
index 896b000..c6caf9d 100644
--- a/gdb/inline-frame.c
+++ b/gdb/inline-frame.c
@@ -300,10 +300,18 @@ stopped_by_user_bp_inline_frame (const block *frame_block, bpstat stop_chain)
bp_location *loc = s->bp_location_at;
enum bp_loc_type t = loc->loc_type;
- if ((t == bp_loc_software_breakpoint
- || t == bp_loc_hardware_breakpoint)
- && frame_block == SYMBOL_BLOCK_VALUE (loc->symbol))
- return true;
+ if (t == bp_loc_software_breakpoint
+ || t == bp_loc_hardware_breakpoint)
+ {
+ /* If the location has a function symbol, check whether
+ the frame was for that inlined function. If it has
+ no function symbol, then assume it is. I.e., default
+ to presenting the stop at the innermost inline
+ function. */
+ if (loc->symbol == nullptr
+ || frame_block == SYMBOL_BLOCK_VALUE (loc->symbol))
+ return true;
+ }
}
}