diff --git a/gdb-6.8-inlining-addon.patch b/gdb-6.8-inlining-addon.patch index e1fc741..a5aa613 100644 --- a/gdb-6.8-inlining-addon.patch +++ b/gdb-6.8-inlining-addon.patch @@ -1,7 +1,7 @@ -Index: gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-bt.c +Index: gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-bt.c =================================================================== ---- gdb-6.8.50.20081128.orig/gdb/testsuite/gdb.opt/inline-bt.c 2008-12-10 00:25:31.000000000 +0100 -+++ gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-bt.c 2008-12-10 00:37:26.000000000 +0100 +--- gdb-6.8.50.20081214.orig/gdb/testsuite/gdb.opt/inline-bt.c 2009-02-09 13:28:48.000000000 +0100 ++++ gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-bt.c 2009-02-09 13:28:49.000000000 +0100 @@ -13,10 +13,16 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -21,10 +21,10 @@ Index: gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-bt.c inline int func1(void) { -Index: gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-bt.exp +Index: gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-bt.exp =================================================================== ---- gdb-6.8.50.20081128.orig/gdb/testsuite/gdb.opt/inline-bt.exp 2008-12-10 00:25:31.000000000 +0100 -+++ gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-bt.exp 2008-12-10 00:37:26.000000000 +0100 +--- gdb-6.8.50.20081214.orig/gdb/testsuite/gdb.opt/inline-bt.exp 2009-02-09 13:28:48.000000000 +0100 ++++ gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-bt.exp 2009-02-09 13:28:49.000000000 +0100 @@ -41,18 +41,19 @@ if { [skip_inline_frame_tests] } { return } @@ -53,10 +53,10 @@ Index: gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-bt.exp gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (3)" gdb_test "backtrace" "#0 bar.*#1 .*func1.*#2 .*func2.*#3 .*main.*" \ -Index: gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-cmds.c +Index: gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-cmds.c =================================================================== ---- gdb-6.8.50.20081128.orig/gdb/testsuite/gdb.opt/inline-cmds.c 2008-12-10 00:25:31.000000000 +0100 -+++ gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-cmds.c 2008-12-10 00:37:26.000000000 +0100 +--- gdb-6.8.50.20081214.orig/gdb/testsuite/gdb.opt/inline-cmds.c 2009-02-09 13:28:48.000000000 +0100 ++++ gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-cmds.c 2009-02-09 13:28:49.000000000 +0100 @@ -13,13 +13,19 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -79,11 +79,11 @@ Index: gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-cmds.c inline int func1(void) { bar (); -Index: gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-cmds.exp +Index: gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-cmds.exp =================================================================== ---- gdb-6.8.50.20081128.orig/gdb/testsuite/gdb.opt/inline-cmds.exp 2008-12-10 00:25:31.000000000 +0100 -+++ gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-cmds.exp 2008-12-10 00:36:27.000000000 +0100 -@@ -45,9 +45,9 @@ if { [skip_inline_frame_tests] } { +--- gdb-6.8.50.20081214.orig/gdb/testsuite/gdb.opt/inline-cmds.exp 2009-02-09 13:28:48.000000000 +0100 ++++ gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-cmds.exp 2009-02-09 13:30:16.000000000 +0100 +@@ -45,28 +45,28 @@ if { [skip_inline_frame_tests] } { # First, check that the things we expected to be inlined really were, # and those that shouldn't be weren't. @@ -94,20 +94,89 @@ Index: gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-cmds.exp +set line2 [gdb_get_line_number "set breakpoint 2 here" ${srcfile2}] gdb_breakpoint $srcfile2:$line2 - gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (1)" -@@ -66,7 +66,7 @@ gdb_test "info frame" ".*inlined into fr +-gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (1)" ++gdb_test "continue" "set breakpoint 1 here.*" "continue to bar (1)" + gdb_test "backtrace" "#0 bar.*#1 .*func1.*#2 .*main.*" \ + "backtrace from bar (1)" + gdb_test "up" "#1 .*func1.*" "up from bar (1)" +-gdb_test "info frame" ".*inlined into frame.*" "func1 inlined (1)" ++gdb_test "info frame" "inlined into frame.*" "func1 inlined (1)" - gdb_test "continue" ".*set breakpoint 2 here.*" "continue to marker" +-gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (2)" ++gdb_test "continue" "set breakpoint 1 here.*" "continue to bar (2)" + gdb_test "backtrace" "#0 bar.*#1 .*func1.*#2 .*func2.*#3 .*main.*" \ + "backtrace from bar (2)" + gdb_test "up" "#1 .*func1.*" "up from bar (2)" +-gdb_test "info frame" ".*inlined into frame.*" "func1 inlined (2)" ++gdb_test "info frame" "inlined into frame.*" "func1 inlined (2)" + gdb_test "up" "#2 .*func2.*" "up from func1 (2)" +-gdb_test "info frame" ".*inlined into frame.*" "func2 inlined (2)" ++gdb_test "info frame" "inlined into frame.*" "func2 inlined (2)" + +-gdb_test "continue" ".*set breakpoint 2 here.*" "continue to marker" ++gdb_test "continue" "set breakpoint 2 here.*" "continue to marker" gdb_test "backtrace" "#0 marker.*#1 .*main.*" "backtrace from marker" -gdb_test "info frame" ".*called by frame.*" "marker not inlined" -+gdb_test "info frame" ".*\n called by frame.*" "marker not inlined" ++gdb_test "info frame" "\n called by frame.*" "marker not inlined" # Next, check that we can next over inlined functions. We should not end up # inside any of them. -Index: gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-locals.c +@@ -201,7 +201,7 @@ set line3 [gdb_get_line_number "set brea + gdb_breakpoint $line3 + gdb_continue_to_breakpoint "consecutive func1" + +-gdb_test "next" ".*func1 .*first call.*" "next to first func1" ++gdb_test "next" "func1 .*first call.*" "next to first func1" + set msg "next to second func1" + gdb_test_multiple "next" $msg { + -re ".*func1 .*second call.*$gdb_prompt $" { +@@ -224,16 +224,16 @@ set line4 [gdb_get_line_number "set brea + gdb_breakpoint $line4 + gdb_continue_to_breakpoint "func1 then func3" + +-gdb_test "next" ".*func1 \\\(\\\);" "next to func1 before func3" +-gdb_test "next" ".*func3 \\\(\\\);" "next to func3" ++gdb_test "next" "func1 \\\(\\\);" "next to func1 before func3" ++gdb_test "next" "func3 \\\(\\\);" "next to func3" + + # Test finishing out of one thing and into another. + set line5 [gdb_get_line_number "set breakpoint 5 here"] + gdb_breakpoint $line5 + gdb_continue_to_breakpoint "finish into func1" + +-gdb_test "next" ".*marker \\\(\\\);" "next to finish marker" +-gdb_test "step" ".*set breakpoint 2 here.*" "step into finish marker" ++gdb_test "next" "marker \\\(\\\);" "next to finish marker" ++gdb_test "step" "set breakpoint 2 here.*" "step into finish marker" + gdb_test "finish" "func1 \\\(\\\);" "finish from marker to func1" + + gdb_test "step" "bar \\\(\\\);" "step into func1 for finish" +@@ -268,12 +268,12 @@ gdb_test "step" "noinline \\\(\\\) at .* + gdb_test "bt" "#0 noinline.*#1 .*outer_inline1.*#2 .*outer_inline2.*#3 main.*" "backtrace at noinline from outer_inline1" + gdb_test "step" "inlined_fn \\\(\\\) at .*" "enter inlined_fn from noinline" + gdb_test "bt" "#0 inlined_fn.*#1 noinline.*#2 .*outer_inline1.*#3 .*outer_inline2.*#4 main.*" "backtrace at inlined_fn from noinline" +-gdb_test "info frame" ".*inlined into frame.*" "inlined_fn from noinline inlined" +-gdb_test "up" "#1 noinline.*" "up to noinline" +-gdb_test "info frame" ".*\n called by frame.*" "noinline from outer_inline1 not inlined" +-gdb_test "up" "#2 .*outer_inline1.*" "up to outer_inline1" +-gdb_test "info frame" ".*inlined into frame.*" "outer_inline1 inlined" +-gdb_test "up" "#3 .*outer_inline2.*" "up to outer_inline2" +-gdb_test "info frame" ".*inlined into frame.*" "outer_inline2 inlined" +-gdb_test "up" "#4 main.*" "up from outer_inline2" +-gdb_test "info frame" ".*\n caller of frame.*" "main not inlined" ++gdb_test "info frame" "inlined into frame.*" "inlined_fn from noinline inlined" ++gdb_test "fini" "" "up to noinline" ++gdb_test "info frame" "\n called by frame.*" "noinline from outer_inline1 not inlined" ++gdb_test "fini" "" "up to outer_inline1" ++gdb_test "info frame" "inlined into frame.*" "outer_inline1 inlined" ++gdb_test "fini" "" "up to outer_inline2" ++gdb_test "info frame" "inlined into frame.*" "outer_inline2 inlined" ++gdb_test "fini" "" "up from outer_inline2" ++gdb_test "info frame" " in main \[^\n\]*\n source language.*" "main not inlined" +Index: gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-locals.c =================================================================== ---- gdb-6.8.50.20081128.orig/gdb/testsuite/gdb.opt/inline-locals.c 2008-12-10 00:25:31.000000000 +0100 -+++ gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-locals.c 2008-12-10 00:37:26.000000000 +0100 +--- gdb-6.8.50.20081214.orig/gdb/testsuite/gdb.opt/inline-locals.c 2009-02-09 13:28:48.000000000 +0100 ++++ gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-locals.c 2009-02-09 13:28:49.000000000 +0100 @@ -13,11 +13,16 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -127,10 +196,10 @@ Index: gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-locals.c inline int func1(int arg1) { -Index: gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-locals.exp +Index: gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-locals.exp =================================================================== ---- gdb-6.8.50.20081128.orig/gdb/testsuite/gdb.opt/inline-locals.exp 2008-12-10 00:25:31.000000000 +0100 -+++ gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-locals.exp 2008-12-10 00:37:26.000000000 +0100 +--- gdb-6.8.50.20081214.orig/gdb/testsuite/gdb.opt/inline-locals.exp 2009-02-09 13:28:48.000000000 +0100 ++++ gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-locals.exp 2009-02-09 13:28:49.000000000 +0100 @@ -43,8 +43,8 @@ if { [skip_inline_var_tests] } { set no_frames [skip_inline_frame_tests] @@ -160,10 +229,10 @@ Index: gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-locals.exp + setup_kfail *-*-* "gcc/debug.optimization" +} gdb_test "print array\[0\]" "\\\$$decimal = 184" "print local (3)" -Index: gdb-6.8.50.20081128/gdb/frame.c +Index: gdb-6.8.50.20081214/gdb/frame.c =================================================================== ---- gdb-6.8.50.20081128.orig/gdb/frame.c 2008-12-10 00:25:31.000000000 +0100 -+++ gdb-6.8.50.20081128/gdb/frame.c 2008-12-10 00:25:31.000000000 +0100 +--- gdb-6.8.50.20081214.orig/gdb/frame.c 2009-02-09 13:28:48.000000000 +0100 ++++ gdb-6.8.50.20081214/gdb/frame.c 2009-02-09 13:30:16.000000000 +0100 @@ -269,7 +269,7 @@ fprint_frame (struct ui_file *file, stru static struct frame_info * skip_inlined_frames (struct frame_info *frame) @@ -173,10 +242,37 @@ Index: gdb-6.8.50.20081128/gdb/frame.c frame = get_prev_frame (frame); return frame; -Index: gdb-6.8.50.20081128/gdb/breakpoint.c +@@ -1697,6 +1697,7 @@ get_frame_address_in_block (struct frame + { + /* A draft address. */ + CORE_ADDR pc = get_frame_pc (this_frame); ++ struct thread_info *tp = inferior_thread (); + + struct frame_info *next_frame = this_frame->next; + +@@ -1739,6 +1740,9 @@ get_frame_address_in_block (struct frame + while in an inlined function, then the code address of the + "calling" normal function should not be adjusted either. */ + ++ if (tp->current_pc_is_notcurrent) ++ return pc - 1; ++ + while (get_frame_type (next_frame) == INLINE_FRAME) + next_frame = next_frame->next; + +@@ -1770,7 +1774,7 @@ find_frame_sal (struct frame_info *frame + sym = inline_skipped_symbol (inferior_ptid); + + init_sal (sal); +- if (SYMBOL_LINE (sym) != 0) ++ if (sym != NULL && SYMBOL_LINE (sym) != 0) + { + sal->symtab = SYMBOL_SYMTAB (sym); + sal->line = SYMBOL_LINE (sym); +Index: gdb-6.8.50.20081214/gdb/breakpoint.c =================================================================== ---- gdb-6.8.50.20081128.orig/gdb/breakpoint.c 2008-12-10 00:25:31.000000000 +0100 -+++ gdb-6.8.50.20081128/gdb/breakpoint.c 2008-12-10 00:36:27.000000000 +0100 +--- gdb-6.8.50.20081214.orig/gdb/breakpoint.c 2009-02-09 13:28:48.000000000 +0100 ++++ gdb-6.8.50.20081214/gdb/breakpoint.c 2009-02-09 13:30:16.000000000 +0100 @@ -57,6 +57,7 @@ #include "top.h" #include "wrapper.h" @@ -185,7 +281,36 @@ Index: gdb-6.8.50.20081128/gdb/breakpoint.c #include "mi/mi-common.h" -@@ -2976,6 +2977,12 @@ bpstat_stop_status (CORE_ADDR bp_addr, p +@@ -2833,10 +2834,24 @@ bpstat_check_breakpoint_conditions (bpst + const struct bp_location *bl = bs->breakpoint_at; + struct breakpoint *b = bl->owner; + +- if (frame_id_p (b->frame_id) +- && !frame_id_eq (b->frame_id, get_stack_frame_id (get_current_frame ()))) +- bs->stop = 0; +- else if (bs->stop) ++ if (frame_id_p (b->frame_id)) ++ { ++ struct frame_info *b_frame, *frame; ++ struct frame_id b_frame_id, current_frame_id; ++ ++ b_frame = frame_find_by_id (b->frame_id); ++ ++ /* get_stack_frame_id normalizes the id to the real non-inlined function ++ by skip_inlined_frames. */ ++ b_frame_id = get_stack_frame_id (b_frame); ++ current_frame_id = get_stack_frame_id (get_current_frame ()); ++ ++ /* Completely different (inlining notwithstanding) frames? */ ++ if (!frame_id_eq (b_frame_id, current_frame_id)) ++ bs->stop = 0; ++ } ++ ++ if (bs->stop) + { + int value_is_zero = 0; + +@@ -2975,6 +2990,12 @@ bpstat_stop_status (CORE_ADDR bp_addr, p bs->print = 0; } bs->commands = copy_command_lines (bs->commands); @@ -198,10 +323,23 @@ Index: gdb-6.8.50.20081128/gdb/breakpoint.c } /* Print nothing for this entry if we dont stop or if we dont print. */ -Index: gdb-6.8.50.20081128/gdb/inline-frame.c +@@ -4826,9 +4847,9 @@ set_momentary_breakpoint (struct symtab_ + { + struct breakpoint *b; + +- /* If FRAME_ID is valid, it should be a real frame, not an inlined +- one. */ +- gdb_assert (!frame_id_inlined_p (frame_id)); ++ /* We can be returning even into an inline frame. While finish_command will ++ shortcut the case of returning _from_ an inline frame we still may be ++ returning from non-inlined frame _to_ an inlined frame. */ + + b = set_raw_breakpoint (sal, type); + b->enable_state = bp_enabled; +Index: gdb-6.8.50.20081214/gdb/inline-frame.c =================================================================== ---- gdb-6.8.50.20081128.orig/gdb/inline-frame.c 2008-12-10 00:25:31.000000000 +0100 -+++ gdb-6.8.50.20081128/gdb/inline-frame.c 2008-12-10 00:40:49.000000000 +0100 +--- gdb-6.8.50.20081214.orig/gdb/inline-frame.c 2009-02-09 13:28:48.000000000 +0100 ++++ gdb-6.8.50.20081214/gdb/inline-frame.c 2009-02-09 13:30:16.000000000 +0100 @@ -183,6 +183,12 @@ inline_frame_sniffer (const struct frame if (frame_block == NULL) return 0; @@ -254,10 +392,34 @@ Index: gdb-6.8.50.20081128/gdb/inline-frame.c if (skip_count != 0) reinit_frame_cache (); -Index: gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-markers.c +@@ -329,6 +334,23 @@ step_into_inline_frame (ptid_t ptid) + reinit_frame_cache (); + } + ++/* Step out of an inlined function by hiding it. */ ++ ++void ++step_out_of_inline_frame (ptid_t ptid) ++{ ++ struct inline_state *state = find_inline_frame_state (ptid); ++ ++ gdb_assert (state != NULL); ++ ++ /* Simulate the caller adjustment. */ ++ if (state->skipped_frames == 0) ++ state->saved_pc--; ++ ++ state->skipped_frames++; ++ reinit_frame_cache (); ++} ++ + /* Return the number of hidden functions inlined into the current + frame. */ + +Index: gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-markers.c =================================================================== ---- gdb-6.8.50.20081128.orig/gdb/testsuite/gdb.opt/inline-markers.c 2008-12-10 00:25:31.000000000 +0100 -+++ gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-markers.c 2008-12-10 00:37:26.000000000 +0100 +--- gdb-6.8.50.20081214.orig/gdb/testsuite/gdb.opt/inline-markers.c 2009-02-09 13:28:48.000000000 +0100 ++++ gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-markers.c 2009-02-09 13:28:49.000000000 +0100 @@ -15,11 +15,6 @@ extern int x, y; @@ -270,3 +432,192 @@ Index: gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-markers.c void marker(void) { x += y; /* set breakpoint 2 here */ +Index: gdb-6.8.50.20081214/gdb/gdbthread.h +=================================================================== +--- gdb-6.8.50.20081214.orig/gdb/gdbthread.h 2009-02-09 13:28:48.000000000 +0100 ++++ gdb-6.8.50.20081214/gdb/gdbthread.h 2009-02-09 13:30:16.000000000 +0100 +@@ -180,6 +180,12 @@ struct thread_info + + /* Private data used by the target vector implementation. */ + struct private_thread_info *private; ++ ++ /* Nonzero if the current frame PC should be unwound as the caller. It is ++ used to keep the backtrace upper levels existing after finish_command into ++ an inlined frame if the current inlined function/block was ending at the ++ current PC. */ ++ int current_pc_is_notcurrent; + }; + + /* Create an empty thread list, or empty the existing one. */ +Index: gdb-6.8.50.20081214/gdb/infcmd.c +=================================================================== +--- gdb-6.8.50.20081214.orig/gdb/infcmd.c 2009-02-09 13:28:48.000000000 +0100 ++++ gdb-6.8.50.20081214/gdb/infcmd.c 2009-02-09 13:30:16.000000000 +0100 +@@ -1373,11 +1373,11 @@ finish_command_continuation (void *arg) + struct type *value_type; + + value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (a->function)); +- if (!value_type) ++ if (!SYMBOL_INLINED (a->function) && !value_type) + internal_error (__FILE__, __LINE__, + _("finish_command: function has no target type")); + +- if (TYPE_CODE (value_type) != TYPE_CODE_VOID) ++ if (value_type && TYPE_CODE (value_type) != TYPE_CODE_VOID) + print_return_value (SYMBOL_TYPE (a->function), value_type); + } + +@@ -1481,6 +1481,16 @@ finish_forward (struct symbol *function, + + old_chain = make_cleanup_delete_breakpoint (breakpoint); + ++ /* We should _always_ set CURRENT_PC_IS_NOTCURRENT here to always see the ++ calling line with the message `Value returned is ...'. Currently it is ++ seen only if at least one instruction is on that source line after the ++ call instruction. We would also need to hook step_once and only clear ++ CURRENT_PC_IS_NOTCURRENT on the first step. But it would be a change of ++ general non-inlining behavior against upstream. */ ++ ++ if (get_frame_type (frame) == INLINE_FRAME) ++ tp->current_pc_is_notcurrent = 1; ++ + tp->proceed_to_finish = 1; /* We want stop_registers, please... */ + make_cleanup_restore_integer (&suppress_stop_observer); + suppress_stop_observer = 1; +@@ -1504,7 +1514,9 @@ finish_forward (struct symbol *function, + static void + finish_command (char *arg, int from_tty) + { +- struct frame_info *frame; ++ /* FIXME: Rename `current_frame' to `frame' upon a merge. */ ++ struct frame_info *current_frame, *prev_frame; ++ CORE_ADDR frame_pc; + struct symbol *function; + + int async_exec = 0; +@@ -1535,46 +1547,63 @@ finish_command (char *arg, int from_tty) + if (!target_has_execution) + error (_("The program is not running.")); + +- frame = get_prev_frame (get_selected_frame (_("No selected frame."))); +- if (frame == 0) ++ current_frame = get_selected_frame (_("No selected frame.")); ++ frame_pc = get_frame_pc (current_frame); ++ prev_frame = get_prev_frame (current_frame); ++ if (prev_frame == 0) + error (_("\"finish\" not meaningful in the outermost frame.")); + +- clear_proceed_status (); +- + /* Finishing from an inline frame is completely different. We don't + try to show the "return value" - no way to locate it. So we do + not need a completion. */ +- if (get_frame_type (get_selected_frame (_("No selected frame."))) +- == INLINE_FRAME) ++ if (get_frame_type (current_frame) == INLINE_FRAME) + { + struct thread_info *tp = inferior_thread (); +- +- /* Claim we are stepping in the calling frame. An empty step +- range means that we will stop once we aren't in a function +- called by that frame. We don't use the magic "1" value for +- step_range_end, because then infrun will think this is nexti, +- and not step over the rest of this inlined function call. */ + struct symtab_and_line empty_sal; +- init_sal (&empty_sal); +- set_step_info (tp, frame, empty_sal); +- tp->step_range_start = tp->step_range_end = get_frame_pc (frame); +- tp->step_over_calls = STEP_OVER_ALL; ++ struct block *frame_block; + + /* Print info on the selected frame, including level number but not + source. */ + if (from_tty) + { + printf_filtered (_("Run till exit from ")); +- print_stack_frame (get_selected_frame (NULL), 1, LOCATION); ++ print_stack_frame (current_frame, 1, LOCATION); + } + ++ /* Even just a single stepi would get us out of the caller function PC ++ range. */ ++ ++ frame_block = get_frame_block (current_frame, NULL); ++ ++ /* FRAME_BLOCK must be initialized and also the frame printing above must ++ be done still with the original CURRENT_PC_IS_NOTCURRENT setting. */ ++ clear_proceed_status (); ++ ++ if (frame_block && BLOCK_END (frame_block) == frame_pc) ++ { ++ step_out_of_inline_frame (tp->ptid); ++ tp->current_pc_is_notcurrent = 1; ++ normal_stop (); ++ return; ++ } ++ ++ /* Claim we are stepping in the calling frame. An empty step ++ range means that we will stop once we aren't in a function ++ called by that frame. We don't use the magic "1" value for ++ step_range_end, because then infrun will think this is nexti, ++ and not step over the rest of this inlined function call. */ ++ init_sal (&empty_sal); ++ set_step_info (tp, prev_frame, empty_sal); ++ tp->step_range_start = tp->step_range_end = get_frame_pc (prev_frame); ++ tp->step_over_calls = STEP_OVER_ALL; ++ + proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1); + return; + } + + /* Find the function we will return from. */ + +- function = find_pc_function (get_frame_pc (get_selected_frame (NULL))); ++ function = find_pc_function (frame_pc); + + /* Print info on the selected frame, including level number but not + source. */ +@@ -1588,10 +1617,14 @@ finish_command (char *arg, int from_tty) + print_stack_frame (get_selected_frame (NULL), 1, LOCATION); + } + ++ /* Frames printing above must be done still with the original ++ CURRENT_PC_IS_NOTCURRENT setting. */ ++ clear_proceed_status (); ++ + if (execution_direction == EXEC_REVERSE) + finish_backward (function); + else +- finish_forward (function, frame); ++ finish_forward (function, prev_frame); + } + + +Index: gdb-6.8.50.20081214/gdb/infrun.c +=================================================================== +--- gdb-6.8.50.20081214.orig/gdb/infrun.c 2009-02-09 13:29:51.000000000 +0100 ++++ gdb-6.8.50.20081214/gdb/infrun.c 2009-02-09 13:30:16.000000000 +0100 +@@ -1201,6 +1201,8 @@ clear_proceed_status_thread (struct thre + + /* Discard any remaining commands or status from previous stop. */ + bpstat_clear (&tp->stop_bpstat); ++ ++ tp->current_pc_is_notcurrent = 0; + } + + static int +Index: gdb-6.8.50.20081214/gdb/inline-frame.h +=================================================================== +--- gdb-6.8.50.20081214.orig/gdb/inline-frame.h 2009-02-09 13:28:48.000000000 +0100 ++++ gdb-6.8.50.20081214/gdb/inline-frame.h 2009-02-09 13:30:16.000000000 +0100 +@@ -43,6 +43,10 @@ void clear_inline_frame_state (ptid_t pt + + void step_into_inline_frame (ptid_t ptid); + ++/* Step out of an inlined function by hiding it. */ ++ ++void step_out_of_inline_frame (ptid_t ptid); ++ + /* Return the number of hidden functions inlined into the current + frame. */ + diff --git a/gdb.spec b/gdb.spec index 4635091..72a0c1d 100644 --- a/gdb.spec +++ b/gdb.spec @@ -13,7 +13,7 @@ Version: 6.8.50.20081214 # The release always contains a leading reserved number, start it at 1. # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing. -Release: 1%{?_with_upstream:.upstream}%{?dist} +Release: 2%{?_with_upstream:.upstream}%{?dist} License: GPLv3+ Group: Development/Debuggers @@ -834,6 +834,8 @@ fi %endif %changelog +* Mon Feb 9 2009 Jan Kratochvil - 6.8.50.20081214-2 +- Fix crash / implement `finish' into inlined functions (BZ 479781). - Drop the gdb.threads/attach-into-signal.exp change as obsolete. * Sun Dec 14 2008 Jan Kratochvil - 6.8.50.20081214-1