This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch] Fixed i386 frameless access
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Mon, 30 Jul 2007 10:28:54 +0200
- Subject: [patch] Fixed i386 frameless access
Hi,
GDB refuses to access i386 CPU registers if no frame has been detected with:
(gdb) set $eax = 3
Value being assigned to is no longer active.
Attached patch ports the existing amd64 code for i386.
Attached testcase expects to be able to compile with "-m32" on amd64/gcc, is it
an acceptable expectations?
Testcase(+me) does not fully test the proper access of the further frames
information.
Regards,
Jan
>From the original bugreport:
----- ps.S
#include <asm/unistd.h>
_start: .globl _start
sub %ebx,%ebx
int3
jnz good
incl %ebx
good:
movl $__NR_exit,%eax
int $0x80
-----
$ gcc -o ps -nostartfiles -nostdlib ps.S
$ gdb ps
(gdb) run
Program received signal SIGTRAP, Trace/breakpoint trap.
0x08048057 in _start ()
(gdb) set $eax = 3
Value being assigned to is no longer active.
Original bugreport from John Reiser:
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=250024
2007-07-30 Jan Kratochvil <jan.kratochvil@redhat.com>
* i386-tdep.c (i386_frame_cache): Fixed registers access for functions
without detected frame - backport of the amd64 variant.
2007-07-30 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.arch/i386-frameless.c, gdb.arch/i386-frameless.S: New files.
--- ./gdb/i386-tdep.c 18 Jun 2007 17:45:26 -0000 1.238
+++ ./gdb/i386-tdep.c 29 Jul 2007 22:43:44 -0000
@@ -943,8 +943,23 @@ i386_frame_cache (struct frame_info *nex
They (usually) share their frame pointer with the frame that was
in progress when the signal occurred. */
- frame_unwind_register (next_frame, I386_EBP_REGNUM, buf);
- cache->base = extract_unsigned_integer (buf, 4);
+ if (cache->locals < 0)
+ {
+ /* We didn't find a valid frame. If we're at the start of a
+ function, or somewhere half-way its prologue, the function's
+ frame probably hasn't been fully setup yet. Try to
+ reconstruct the base address for the stack frame by looking
+ at the stack pointer. For truly "frameless" functions this
+ might work too. */
+ frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
+ cache->base = extract_unsigned_integer (buf, 4) + cache->sp_offset;
+ }
+ else
+ {
+ frame_unwind_register (next_frame, I386_EBP_REGNUM, buf);
+ cache->base = extract_unsigned_integer (buf, 4);
+ }
+
if (cache->base == 0)
return cache;
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.arch/i386-frameless.S 30 Jul 2007 08:25:57 -0000
@@ -0,0 +1,29 @@
+/* Copyright 2007 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Please email any bugs, comments, and/or additions to this file to:
+ * bug-gdb@gnu.org
+ *
+ * This file is part of the gdb testsuite.
+ */
+
+#include <asm/unistd.h>
+
+_start: .globl _start
+ sub %ebx,%ebx
+ int3
+ movl $__NR_exit,%eax
+ int $0x80
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.arch/i386-frameless.exp 30 Jul 2007 08:25:57 -0000
@@ -0,0 +1,73 @@
+# Copyright 2007 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+# This file is part of the gdb testsuite.
+
+# i386-linux frameless registers access test.
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+# Test i386 unwinder.
+
+set prms_id 0
+set bug_id 0
+
+set testfile "i386-frameless"
+set srcfile ${testfile}.S
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+if {![istarget "i?86-*-linux*"] && ![istarget "x86_64-*-linux*"]
+ || ![test_compiler_info gcc*]} then {
+ verbose "Skipping i386 unwinder tests."
+ return
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug {additional_flags=-m32 -nostartfiles -nostdlib}]] != "" } {
+ untested i386-frameless.exp
+ return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# We should stop in abort(3).
+
+gdb_run_cmd
+
+gdb_test_multiple {} "continue to int3" {
+ -re ".*Program received signal SIGTRAP,.*$gdb_prompt $" {
+ pass "continue to int3"
+ }
+}
+
+# FAIL here was: Value being assigned to is no longer active.
+# The exit code is printed in octal - adapt to it.
+gdb_test "set \$ebx=042"
+
+gdb_test "continue" "\nProgram exited with code 042." "Register change check"