From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21597 invoked by alias); 17 Nov 2008 02:35:56 -0000 Received: (qmail 21531 invoked by uid 22791); 17 Nov 2008 02:35:54 -0000 X-Spam-Check-By: sourceware.org Received: from smtp-outbound-2.vmware.com (HELO smtp-outbound-2.vmware.com) (65.115.85.73) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 17 Nov 2008 02:35:00 +0000 Received: from mailhost5.vmware.com (mailhost5.vmware.com [10.16.68.131]) by smtp-outbound-2.vmware.com (Postfix) with ESMTP id A431D4005; Sun, 16 Nov 2008 18:34:58 -0800 (PST) Received: from [10.20.92.59] (promb-2s-dhcp59.eng.vmware.com [10.20.92.59]) by mailhost5.vmware.com (Postfix) with ESMTP id A03CDDC0B3; Sun, 16 Nov 2008 18:34:58 -0800 (PST) Message-ID: <4920D821.5090201@vmware.com> Date: Mon, 17 Nov 2008 20:02:00 -0000 From: Michael Snyder User-Agent: Thunderbird 1.5.0.12 (X11/20080411) MIME-Version: 1.0 To: Doug Evans CC: "gdb-patches@sourceware.org" Subject: Re: [RFA] fix popping of dummy frame if inferior gets signal with unwindonsignal References: <20081116011325.DE3CB4125E1@localhost> In-Reply-To: <20081116011325.DE3CB4125E1@localhost> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-11/txt/msg00429.txt.bz2 I don't understand why calling dummy_frame_pop directly works, but calling frame_pop doesn't work. Doesn't frame_pop call dummy_frame_pop? If not, what prevents it? Doug Evans wrote: > Hi. This fixes a bug where a signal in an inferior function call with > unwindonsignal set doesn't remove the dummy frame from dummy_frame_stack. > A testcase is included to exercise the bug. > > It also adds a comment to clear up something that was a bit confusing > at first. The lone frame_pop isn't enough to properly restore program > state, but things still work because registers (and thus stack) get > restored from inf_status. > > Tested on i386-linux. > > Ok to check in? > > 2008-11-15 Doug Evans > > * infcall.c (call_function_by_hand): Properly pop the dummy frame > if the inferior gets a signal and unwindonsignal is set. > > * gdb.base/unwindonsignal.c: New file. > * gdb.base/unwindonsignal.exp: New file. > > Index: infcall.c > =================================================================== > RCS file: /cvs/src/src/gdb/infcall.c,v > retrieving revision 1.105 > diff -u -p -u -p -r1.105 infcall.c > --- infcall.c 12 Nov 2008 00:39:28 -0000 1.105 > +++ infcall.c 15 Nov 2008 22:08:54 -0000 > @@ -357,7 +358,10 @@ call_function_by_hand (struct value *fun > /* Save the caller's registers so that they can be restored once the > callee returns. To allow nested calls the registers are (further > down) pushed onto a dummy frame stack. Include a cleanup (which > - is tossed once the regcache has been pushed). */ > + is tossed once the regcache has been pushed). > + NOTE: If the inferior gets a signal and unwindonsignal is set, > + then this regcache is not used to restore target regs. Instead > + the regcache in inf_status is used. */ > caller_regcache = frame_save_as_regcache (frame); > caller_regcache_cleanup = make_cleanup_regcache_xfree (caller_regcache); > > @@ -746,8 +749,12 @@ The program being debugged exited while > /* The user wants the context restored. */ > > /* We must get back to the frame we were before the > - dummy call. */ > - frame_pop (get_current_frame ()); > + dummy call. > + NOTE: This discards the regcache recorded in the dummy frame > + but that's ok, the registers will get restored from the > + regcache in inf_status (which gets called by a cleanup). */ > + dummy_frame_pop (dummy_id); > + reinit_frame_cache (); > > /* FIXME: Insert a bunch of wrap_here; name can be very > long if it's a C++ name with arguments and stuff. */ > Index: testsuite/gdb.base/unwindonsignal.c > =================================================================== > RCS file: testsuite/gdb.base/unwindonsignal.c > diff -N testsuite/gdb.base/unwindonsignal.c > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ testsuite/gdb.base/unwindonsignal.c 16 Nov 2008 01:11:22 -0000 > @@ -0,0 +1,49 @@ > +/* This testcase is part of GDB, the GNU debugger. > + > + Copyright 2008 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 . */ > + > +/* Support program for testing handling of unwindonsignal. */ > + > +#include > +#include > +#include > + > +/* This function is handcalled from unwindonsignal.exp. */ > + > +void > +gen_signal () > +{ > + /* According to sigall.exp, SIGABRT is always supported, > + so try that first. */ > +#ifdef SIGABRT > + kill (getpid (), SIGABRT); > +#endif > +#ifdef SIGSEGV > + kill (getpid (), SIGSEGV); > +#endif > + /* If we get here we couldn't generate a signal, tell dejagnu. */ > + printf ("no signal\n"); > +} > + > +int > +main () > +{ > +#ifdef usestubs > + set_debug_traps (); > + breakpoint (); > +#endif > + return 0; > +} > Index: testsuite/gdb.base/unwindonsignal.exp > =================================================================== > RCS file: testsuite/gdb.base/unwindonsignal.exp > diff -N testsuite/gdb.base/unwindonsignal.exp > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ testsuite/gdb.base/unwindonsignal.exp 16 Nov 2008 01:11:22 -0000 > @@ -0,0 +1,94 @@ > +# Copyright 2008 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 . > + > +if $tracelevel then { > + strace $tracelevel > +} > + > +if [target_info exists gdb,noinferiorio] { > + verbose "Skipping unwindonsignal.exp because of no fileio capabilities." > + continue > +} > + > +set prms_id 0 > +set bug_id 0 > + > +set testfile "unwindonsignal" > +set srcfile ${testfile}.c > +set binfile ${objdir}/${subdir}/${testfile} > + > +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { > + untested unwindonsignal.exp > + return -1 > +} > + > +# Some targets can't do function calls, so don't even bother with this > +# test. > +if [target_info exists gdb,cannot_call_functions] { > + setup_xfail "*-*-*" 2416 > + fail "This target can not call functions" > + continue > +} > + > +# Start with a fresh gdb. > + > +gdb_exit > +gdb_start > +gdb_reinitialize_dir $srcdir/$subdir > +gdb_load ${binfile} > + > +if { ![runto_main] } { > + fail "Can't run to main" > + return 0 > +} > + > +# Turn on unwindonsignal. > +gdb_test "set unwindonsignal on" \ > + "" \ > + "setting unwindonsignal" > +gdb_test "show unwindonsignal" \ > + "Unwinding of stack .* is on." \ > + "showing unwindonsignal" > + > +# Call function (causing the program to get a signal), and see if gdb handles > +# it properly. > +gdb_test_multiple "call gen_signal ()" \ > + "unwindonsignal, inferior function call signaled" { > + -re "\[\r\n\]*no signal\[\r\n\]+$gdb_prompt $" { > + unsupported "unwindonsignal, inferior function call signaled" > + return 0 > + } > + -re "\[\r\n\]*The program being debugged was signaled.*\[\r\n\]+$gdb_prompt $" { > + pass "unwindonsignal, inferior function call signaled" > + } > +} > + > +# Verify the stack got unwound. > +gdb_test "bt" \ > + "#0 *main \\(.*\\) at .*" \ > + "unwindonsignal, stack unwound" > + > +# Verify the dummy frame got removed from dummy_frame_stack. > +gdb_test_multiple "maint print dummy-frames" \ > + "unwindonsignal, dummy frame removed" { > + -re "\[\r\n\]*.*stack=.*code=.*\[\r\n\]+$gdb_prompt $" { > + fail "unwindonsignal, dummy frame removed" > + } > + -re "\[\r\n\]+$gdb_prompt $" { > + pass "unwindonsignal, dummy frame removed" > + } > +} > + > +return 0