This is the mail archive of the gdb-patches@sourceware.org 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]

[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"
+



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