rpms/gdb/devel gdb-6.8-inlining-addon.patch, 1.1, 1.2 gdb.spec, 1.319, 1.320

Jan Kratochvil jkratoch at fedoraproject.org
Mon Feb 9 12:35:37 UTC 2009


Author: jkratoch

Update of /cvs/pkgs/rpms/gdb/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv1383

Modified Files:
	gdb-6.8-inlining-addon.patch gdb.spec 
Log Message:
* Mon Feb  9 2009 Jan Kratochvil <jan.kratochvil at redhat.com> - 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.


gdb-6.8-inlining-addon.patch:

Index: gdb-6.8-inlining-addon.patch
===================================================================
RCS file: /cvs/pkgs/rpms/gdb/devel/gdb-6.8-inlining-addon.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- gdb-6.8-inlining-addon.patch	14 Dec 2008 14:05:18 -0000	1.1
+++ gdb-6.8-inlining-addon.patch	9 Feb 2009 12:35:37 -0000	1.2
@@ -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 <http://www.gnu.org/licenses/>.  */
@@ -21,10 +21,10 @@
  
  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 @@
  
  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 <http://www.gnu.org/licenses/>.  */
@@ -79,11 +79,11 @@
  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 @@
 +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 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 "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 <http://www.gnu.org/licenses/>.  */
@@ -127,10 +196,10 @@
  
  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 @@
 +    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 @@
      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 @@
  
  #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 @@
        }
  
      /* 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 @@
  
    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 @@
  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.  */
+ 


Index: gdb.spec
===================================================================
RCS file: /cvs/pkgs/rpms/gdb/devel/gdb.spec,v
retrieving revision 1.319
retrieving revision 1.320
diff -u -r1.319 -r1.320
--- gdb.spec	5 Feb 2009 15:54:27 -0000	1.319
+++ gdb.spec	9 Feb 2009 12:35:37 -0000	1.320
@@ -13,7 +13,7 @@
 
 # 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 @@
 %endif
 
 %changelog
+* Mon Feb  9 2009 Jan Kratochvil <jan.kratochvil at redhat.com> - 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 <jan.kratochvil at redhat.com> - 6.8.50.20081214-1




More information about the scm-commits mailing list