2007-07-30 Jan Kratochvil * i386-tdep.c (i386_frame_cache): Fixed registers access for functions without detected frame - backport of the amd64 variant. 2007-07-30 Jan Kratochvil * 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 + +_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"