This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: report failure to restore selected frame, but continue


2003-04-09  Jim Blandy  <jimb at redhat dot com>

	* gdb.c++/derivation.exp, gdb.c++/overload.exp,
	gdb.c++/userdef.exp: If GDB fails to restore the selected frame
	after an inferior function call, report the failure, but allow the
	test to continue.

Index: gdb/testsuite/gdb.c++/userdef.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.c++/userdef.exp,v
retrieving revision 1.6
diff -c -r1.6 userdef.exp
*** gdb/testsuite/gdb.c++/userdef.exp	18 Feb 2002 19:07:29 -0000	1.6
--- gdb/testsuite/gdb.c++/userdef.exp	9 Apr 2003 21:33:04 -0000
***************
*** 66,71 ****
--- 66,128 ----
  
  gdb_test "print one + two" "\\\$\[0-9\]* = {x = 6, y = 8}"
  
+ # Suppose an architecture uses the stack pointer as its frame base
+ # (that is, the 'base' member of its frame ID).  (Ignore functions
+ # that use alloca for the moment.)  This means that the youngest
+ # frame's base is the top of the stack.  If that function calls a
+ # frameless function, then the caller and callee frames will have
+ # identical base addresses.  frame_id_eq is supposed to use both the
+ # base and pc fields of the ID's to decide whether they're eq, but as
+ # of 4-2003 it doesn't, so code like frame_find_by_id can't
+ # distinguish between those two frames.
+ #
+ # This means that, on such architectures, if the marker function we're
+ # stopped at in this test is frameless, GDB doesn't properly restore
+ # the selected frame after an inferior function call:
+ # infrun.c:restore_selected_frame will select the youngest frame (the
+ # marker function), not its caller (main).
+ #
+ # Changing frame_id_eq isn't really a full solution, though.  By
+ # definition, a frame base is constant over the lifetime of the frame.
+ # However, the stack pointer changes as a function's prologue code
+ # sets up the stack frame, making it unsuitable for use as a frame
+ # base.  The address of the inner end of each frame --- furthest from
+ # the stack pointer --- would work better here; it remains unchanged
+ # through frame allocation, frame teardown, and any alloca'ing that
+ # might happen in between.
+ #
+ # Of course, strictly speaking, that just shifts the problem around:
+ # if there's a younger frame sitting on top of a frameless frame, then
+ # they'll have identical ID's.  But frameless functions can't call
+ # other functions directly, at least using the standard ABI --- they
+ # have no place to save the return address.  Only signal delivery
+ # frames and inferior calls can be there, and those have all sorts of
+ # other associated magic.
+ #
+ # Anyway, if GDB fails to restore the selected frame properly after
+ # the inferior function call above, all the subsequent tests will
+ # fail.  We should detect report that failure, but let the marker call
+ # finish so that the rest of the tests can run undisturbed.
+ 
+ send_gdb "frame\n"
+ gdb_expect {
+     -re "#0  marker1.*$gdb_prompt $" {
+         setup_kfail "gdb/1155" s390-*-linux-gnu
+         fail "re-selected 'main' frame after inferior method call (gdb/1155)"
+         gdb_test "finish" ".*main.*at .*userdef.cc:27\[67\].*" \
+                 "finish call to marker1"
+     }
+     -re "#1  ($hex in )?main.*$gdb_prompt $" {
+         pass "re-selected 'main' frame after inferior method call"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "re-selected 'main' frame after inferior method call"
+     }
+     timeout {
+         fail "re-selected 'main' frame after inferior method call (timeout)"
+     }
+ }
+         
  gdb_test "print one - two" "\\\$\[0-9\]* = {x = -2, y = -2}"
  
  gdb_test "print one * two" "\\\$\[0-9\]* = {x = 8, y = 15}"
Index: gdb/testsuite/gdb.c++/derivation.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.c++/derivation.exp,v
retrieving revision 1.10
diff -c -r1.10 derivation.exp
*** gdb/testsuite/gdb.c++/derivation.exp	20 Jan 2002 19:22:13 -0000	1.10
--- gdb/testsuite/gdb.c++/derivation.exp	9 Apr 2003 21:33:04 -0000
***************
*** 300,305 ****
--- 300,326 ----
      timeout           { fail "(timeout) print value of g_instance.afoo()" }
    }
  
+ 
+ # See explanation in userdef.exp for the test of the same name.
+ send_gdb "frame\n"
+ gdb_expect {
+     -re "#0  marker1.*$gdb_prompt $" {
+         setup_kfail "gdb/1155" s390-*-linux-gnu
+         fail "re-selected 'main' frame after inferior method call (gdb/1155)"
+         gdb_test "finish" ".*main.*at .*derivation.cc:21\[79\].*" \
+             "finish call to marker1"
+     }
+     -re "#1  ($hex in )?main.*$gdb_prompt $" {
+         pass "re-selected 'main' frame after inferior method call"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "re-selected 'main' frame after inferior method call"
+     }
+     timeout {
+         fail "re-selected 'main' frame after inferior method call (timeout)"
+     }
+ }
+         
  send_gdb "print g_instance.bfoo()\n"
  gdb_expect {
      -re ".\[0-9\]* = 2.*$gdb_prompt $" {
Index: gdb/testsuite/gdb.c++/overload.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.c++/overload.exp,v
retrieving revision 1.10
diff -c -r1.10 overload.exp
*** gdb/testsuite/gdb.c++/overload.exp	4 Feb 2003 21:19:27 -0000	1.10
--- gdb/testsuite/gdb.c++/overload.exp	9 Apr 2003 21:33:04 -0000
***************
*** 120,125 ****
--- 120,145 ----
    }
  
  
+ # See explanation in userdef.exp for the test of the same name.
+ send_gdb "frame\n"
+ gdb_expect {
+     -re "#0  marker1.*$gdb_prompt $" {
+         setup_kfail "gdb/1155" s390-*-linux-gnu
+         fail "re-selected 'main' frame after inferior method call (gdb/1155)"
+         gdb_test "finish" ".*main.*at .*overload.cc:7\[78\].*" \
+             "finish call to marker1"
+     }
+     -re "#1  ($hex in )?main.*$gdb_prompt $" {
+         pass "re-selected 'main' frame after inferior method call"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "re-selected 'main' frame after inferior method call"
+     }
+     timeout {
+         fail "re-selected 'main' frame after inferior method call (timeout)"
+     }
+ }
+ 
  send_gdb "print foo_instance1.overloadargs(1, 2)\n"
  gdb_expect {
      -re ".\[0-9\]* = 2\r\n$gdb_prompt $" {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]