This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH] Add temporary frames to frame cache.
- From: "Andrew Burgess" <aburgess at broadcom dot com>
- To: "gdb-patches at sourceware dot org" <gdb-patches at sourceware dot org>
- Date: Fri, 7 Jun 2013 15:36:34 +0100
- Subject: [PATCH] Add temporary frames to frame cache.
Found the following issue,
## START ##
(gdb) break break_me
Breakpoint 1 at 0x400738: file ../../../src/gdb/testsuite/gdb.base/frame-args.c, line 35.
(gdb) r
Starting program: /projects/firepath_work/aburgess/upstream-gdb-git/build/gdb/testsuite/gdb.base/frame-args
Breakpoint 1, break_me ()
at ../../../src/gdb/testsuite/gdb.base/frame-args.c:35
35 }
(gdb) bt
#0 break_me () at ../../../src/gdb/testsuite/gdb.base/frame-args.c:35
#1 0x000000000040075e in call_me (i=3, f=5, s=..., ss=0x7fffffffdef0, u=...,
e=green) at ../../../src/gdb/testsuite/gdb.base/frame-args.c:40
#2 0x00000000004007a3 in main ()
at ../../../src/gdb/testsuite/gdb.base/frame-args.c:53
(gdb) frame 3
#0 0x0000000000000000 in ?? ()
(gdb) info frame
Stack level 0, frame at 0x3:
rip = 0x0; saved rip 0x7fffffffded0
called by frame at 0x7fffffffdeb0
Arglist at 0x7fffffffde98, args:
Locals at 0x7fffffffde98, Previous frame's sp is 0x7fffffffdea8
../../src/gdb/valops.c:1025: internal-error: value_fetch_lazy: Assertion `frame != NULL' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n) y
## END ##
This is because when I do "frame 3" a new frame is created with a call
to create_new_frame at the end of parse_frame_specification_1. However,
in value_fetch_lazy the frame can't be found again.
My solution is to add the new frame to the frame cache from within
create_new_frame, this fixes the issue and shows no regressions on x86-64
Linux.
Feedback welcome, or am I ok to commit?
Thanks,
Andrew
gdb/ChangeLog
2013-06-07 Andrew Burgess <aburgess@broadcom.com>
* frame.c (create_new_frame): Add the new frame to the frame cache
so it can be found again later.
gdb/testsuite/ChangeLog
2013-06-07 Andrew Burgess <aburgess@broadcom.com>
* gdb.base/create-frame.exp: New file. Test that we can "frame
info" on a temporary frame.
diff --git a/gdb/frame.c b/gdb/frame.c
index d52c26a..6c06710 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1562,6 +1562,9 @@ create_new_frame (CORE_ADDR addr, CORE_ADDR pc)
fi->this_id.p = 1;
fi->this_id.value = frame_id_build (addr, pc);
+ /* Add the new frame to the stash so it can be found later. */
+ frame_stash_add (fi);
+
if (frame_debug)
{
fprintf_unfiltered (gdb_stdlog, "-> ");
diff --git a/gdb/testsuite/gdb.base/create-frame.exp b/gdb/testsuite/gdb.base/create-frame.exp
new file mode 100644
index 0000000..0f20f1f
--- /dev/null
+++ b/gdb/testsuite/gdb.base/create-frame.exp
@@ -0,0 +1,46 @@
+# Copyright 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+standard_testfile frame-args.c
+set executable frame-args
+
+if { [prepare_for_testing ${testfile}.exp ${executable}] } {
+ return -1
+}
+
+if ![runto break_me] then {
+ perror "Couldn't run ${testfile}"
+ return
+}
+
+gdb_test "bt" \
+ "#0 break_me\[^\r\n\]+\r\n#1 $hex in call_me\[^\r\n\]+\r\n#2 $hex in main\[^\r\n\]+" \
+ "backtrace from break_me before creating new frame"
+
+# Now switch to a frame not in the current stack, and "frame info"
+gdb_test "frame 3" "#0 $hex in \\?\\?\\s+\\(\\)" "Switch to new frame (#3)"
+gdb_test "info frame" "Stack level 0,.*" "Perform frame info on new frame"
+
+# Check the backtrace is still good.
+gdb_test "bt" \
+ "#0 break_me\[^\r\n\]+\r\n#1 $hex in call_me\[^\r\n\]+\r\n#2 $hex in main\[^\r\n\]+" \
+ "backtrace from break_me after creating new frame"
+
+# Now switch back to a "real" frame, and "frame info".
+gdb_test "frame 1" \
+ "#1 $hex in call_me \\(\[^\r\n\]+\\) at \[^\r\n\]+:\[0-9\]+\r\n\[0-9\]+\\s+break_me \\(\\);" \
+ "Switch to frame #1"
+gdb_test "info frame" "Stack level 1,.*" "Perform frame info on frame #1"
+