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] 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"

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