diff options
author | Gary Benson <gary@redhat.com> | 2011-10-12 15:43:49 +0000 |
---|---|---|
committer | Gary Benson <gary@redhat.com> | 2011-10-12 15:43:49 +0000 |
commit | 0574c78f39bf3ceccbd57bcd1b2973b683e8dd06 (patch) | |
tree | 04a74ddde9da91b87888422e69c59a8cf4bcf97c /gdb/infrun.c | |
parent | ecf8e7f5f6a88a2c180bca7d013f622e46d2b8ec (diff) | |
download | gdb-0574c78f39bf3ceccbd57bcd1b2973b683e8dd06.zip gdb-0574c78f39bf3ceccbd57bcd1b2973b683e8dd06.tar.gz gdb-0574c78f39bf3ceccbd57bcd1b2973b683e8dd06.tar.bz2 |
2011-10-12 Gary Benson <gbenson@redhat.com>
* breakpoint.h (pc_at_non_inline_function): Declare.
* breakpoint.c (is_non_inline_function,
pc_at_non_inline_function): New functions.
* infrun.c (handle_inferior_event): Don't call skip_inline_frames
if the stop is at a location where functions cannot be inlined.
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r-- | gdb/infrun.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c index cc2e29b..db6a5d1 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -4044,7 +4044,32 @@ handle_inferior_event (struct execution_control_state *ecs) nexti. After stepi and nexti, always show the innermost frame (not any inline function call sites). */ if (ecs->event_thread->control.step_range_end != 1) - skip_inline_frames (ecs->ptid); + { + struct address_space *aspace = + get_regcache_aspace (get_thread_regcache (ecs->ptid)); + + /* skip_inline_frames is expensive, so we avoid it if we can + determine that the address is one where functions cannot have + been inlined. This improves performance with inferiors that + load a lot of shared libraries, because the solib event + breakpoint is defined as the address of a function (i.e. not + inline). Note that we have to check the previous PC as well + as the current one to catch cases when we have just + single-stepped off a breakpoint prior to reinstating it. + Note that we're assuming that the code we single-step to is + not inline, but that's not definitive: there's nothing + preventing the event breakpoint function from containing + inlined code, and the single-step ending up there. If the + user had set a breakpoint on that inlined code, the missing + skip_inline_frames call would break things. Fortunately + that's an extremely unlikely scenario. */ + if (!pc_at_non_inline_function (aspace, stop_pc) + && !(ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP + && ecs->event_thread->control.trap_expected + && pc_at_non_inline_function (aspace, + ecs->event_thread->prev_pc))) + skip_inline_frames (ecs->ptid); + } if (ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP && ecs->event_thread->control.trap_expected |