This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
RFA: report failure to restore selected frame, but continue
- From: Jim Blandy <jimb at redhat dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: 09 Apr 2003 16:41:06 -0500
- Subject: 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 $" {