From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27830 invoked by alias); 11 Nov 2008 22:51:36 -0000 Received: (qmail 27666 invoked by uid 22791); 11 Nov 2008 22:51:35 -0000 X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.33.17) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 11 Nov 2008 22:50:33 +0000 Received: from wpaz13.hot.corp.google.com (wpaz13.hot.corp.google.com [172.24.198.77]) by smtp-out.google.com with ESMTP id mABMoMpr008394 for ; Tue, 11 Nov 2008 22:50:23 GMT Received: from localhost (ruffy.corp.google.com [172.18.118.116]) by wpaz13.hot.corp.google.com with ESMTP id mABMoLH6029431 for ; Tue, 11 Nov 2008 14:50:21 -0800 Received: by localhost (Postfix, from userid 67641) id 015C61C79A1; Tue, 11 Nov 2008 14:50:20 -0800 (PST) To: gdb-patches@sourceware.org Subject: [RFA] detect inferior exit in call_function_by_hand Message-Id: <20081111225021.015C61C79A1@localhost> Date: Wed, 12 Nov 2008 08:32:00 -0000 From: dje@google.com (Doug Evans) 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/msg00219.txt.bz2 I found this while playing with the archer exception-rewind branch. The message currently printed when the inferior exits during call_function_by_hand is misleading. [On the branch one currently gets a segv, stopped_by_random_signal/stop_stack_dummy do not fully describe all the possible states of the inferior.] foo.cc: #include char foo () { exit (0); } int main () { return 0; } --- (gdb) start (gdb) call foo () Program exited normally. The program being debugged stopped while in a function called from GDB. When the function (foo()) is done executing, GDB will silently stop (instead of continuing to evaluate the expression containing the function call). (gdb) With the patch gdb prints: (gdb) call foo () Program exited normally. The program being debugged exited while in a function called from GDB. (gdb) Ok to check in? 2008-11-11 Doug Evans * infcall.c (call_function_by_hand): Handle inferior exit. * gdb.base/callexit.exp: New file. * gdb.base/callexit.c: New file. diff --git a/gdb/infcall.c b/gdb/infcall.c index ece57ba..6781989 100644 --- a/gdb/infcall.c +++ b/gdb/infcall.c @@ -746,6 +746,18 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) discard_cleanups (old_cleanups); } + if (! target_has_execution) + { + /* If we try to restore the inferior status (via the cleanup), + we'll crash as the inferior is no longer running. */ + discard_cleanups (inf_status_cleanup); + discard_inferior_status (inf_status); + /* FIXME: Insert a bunch of wrap_here; name can be very long if it's + a C++ name with arguments and stuff. */ + error (_("\ +The program being debugged exited while in a function called from GDB.")); + } + if (stopped_by_random_signal || !stop_stack_dummy) { /* Find the name of the function we're about to complain about. */ diff --git a/gdb/infcall.c b/gdb/infcall.c index ece57ba..6781989 100644 --- a/gdb/testsuite/gdb.base/callexit.exp 2007-10-18 09:27:25.000000000 -0700 +++ b/gdb/testsuite/gdb.base/callexit.exp 2008-11-11 13:45:24.000000000 -0800 @@ -0,0 +1,90 @@ +# 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 +} + +set prms_id 0 +set bug_id 0 + +set testfile "callexit" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested callfuncs.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 +} + +# Set the current language to C. This counts as a test. If it +# fails, then we skip the other tests. + +proc set_lang_c {} { + global gdb_prompt + + send_gdb "set language c\n" + gdb_expect { + -re ".*$gdb_prompt $" {} + timeout { fail "set language c (timeout)" ; return 0; } + } + + send_gdb "show language\n" + gdb_expect { + -re ".* source language is \"c\".*$gdb_prompt $" { + pass "set language to \"c\"" + return 1 + } + -re ".*$gdb_prompt $" { + fail "setting language to \"c\"" + return 0 + } + timeout { + fail "can't show language (timeout)" + return 0 + } + } +} + +# Start with a fresh gdb. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if { ![set_lang_c] } { + gdb_suppress_tests; +} else { + if { ![runto_main] } { + gdb_suppress_tests; + } +} + +# Call function (causing the program to exit), and see if gdb handles +# it properly. +gdb_test "call callexit()" \ + "The program being debugged exited.*" \ + "inferior function call terminated program" + +return 0 diff --git a/gdb/infcall.c b/gdb/infcall.c index ece57ba..6781989 100644 --- a/gdb/testsuite/gdb.base/callexit.c 2007-10-18 09:27:25.000000000 -0700 +++ b/gdb/testsuite/gdb.base/callexit.c 2008-11-11 13:37:56.000000000 -0800 @@ -0,0 +1,33 @@ +/* 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 gdb's ability to handle an + inferior function call that terminates the program. */ + +#include + +void +callexit () +{ + exit (0); +} + +int +main () +{ + return 0; +}