From patchwork Fri Mar 6 19:58:06 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Alves X-Patchwork-Id: 5506 Received: (qmail 109359 invoked by alias); 6 Mar 2015 20:27:34 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 109350 invoked by uid 89); 6 Mar 2015 20:27:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 06 Mar 2015 20:27:32 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t26JwEuf022524 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Fri, 6 Mar 2015 14:58:14 -0500 Received: from brno.lan (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t26Jw60q024787 for ; Fri, 6 Mar 2015 14:58:14 -0500 From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH 6/6] Add test that exercises the inferior being killed while stopped under GDB Date: Fri, 6 Mar 2015 19:58:06 +0000 Message-Id: <1425671886-7798-7-git-send-email-palves@redhat.com> In-Reply-To: <1425671886-7798-1-git-send-email-palves@redhat.com> References: <1425671886-7798-1-git-send-email-palves@redhat.com> This exercises the case of the inferior disappearing while GDB is debugging it, such as something doing "kill -9 PID" while the program is stopped under GDB or GDBserver. This triggered a set of internal errors, fixed by the previous patches. gdb/testsuite/ChangeLog: 2015-03-06 Pedro Alves * gdb.base/killed-outside.exp: New file. * gdb.base/killed-outside.c: New file. --- gdb/testsuite/gdb.base/killed-outside.c | 34 ++++++++ gdb/testsuite/gdb.base/killed-outside.exp | 130 ++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 gdb/testsuite/gdb.base/killed-outside.c create mode 100644 gdb/testsuite/gdb.base/killed-outside.exp diff --git a/gdb/testsuite/gdb.base/killed-outside.c b/gdb/testsuite/gdb.base/killed-outside.c new file mode 100644 index 0000000..f0e9eda --- /dev/null +++ b/gdb/testsuite/gdb.base/killed-outside.c @@ -0,0 +1,34 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2015 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 . */ + +#include +#include + +pid_t pid; + +static void +done (void) +{ +} + +int +main (int argc, char **argv) +{ + pid = getpid (); + done (); + return 0; +} diff --git a/gdb/testsuite/gdb.base/killed-outside.exp b/gdb/testsuite/gdb.base/killed-outside.exp new file mode 100644 index 0000000..1e8c0d3 --- /dev/null +++ b/gdb/testsuite/gdb.base/killed-outside.exp @@ -0,0 +1,130 @@ +# Copyright 2015 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 . + +# Test that GDB doesn't get badly wedged if the inferior is killed +# from outside GDB (with SIGKILL) while the program is stopped. + +standard_testfile + +# Get the value of variable VAR in the inferior. MSG is used as the +# test message. + +proc get_value {var msg} { + global expect_out + global gdb_prompt + global decimal + + set value -1 + gdb_test_multiple "print $var" "$msg" { + -re ".*= ($decimal).*\r\n$gdb_prompt $" { + set value $expect_out(1,string) + pass "$msg" + } + } + return ${value} +} + +# Runs the program until a breakpoint, deletes all breakpoints, and +# then kills the inferior from _outside_ GDB, with SIGKILL. Runs CMDS +# afterwards, to make sure GDB copes with the inferior disappearing, +# and then quits GDB. + +proc test {cmds_after_kill} { + global binfile + global gdb_prompt + global decimal + + clean_restart ${binfile} + + if ![runto done] { + return + } + + # So that "continue" doesn't try a step over, etc. + delete_breakpoints + + set testpid [get_value "pid" "get pid of inferior"] + if { $testpid == -1 } { + return -1 + } + + remote_exec target "kill -9 ${testpid}" + + # Give it some time to die. + sleep 2 + + uplevel 1 $cmds_after_kill + + # Make sure we can quit. + set msg "quit GDB" + gdb_test_multiple "quit" $msg { + -re "Quit anyway\\? \\(y or n\\) $" { + send_gdb "y\n" + exp_continue + } + eof { + pass $msg + } + } +} + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile $options] == -1} { + return -1 +} + +# The actual output GDB prints in response to commands after the +# inferior is gone isn't very well defined, and will depend on target. +# What we're trying to make sure is that GDB doesn't internal error or +# get wedged. + +# Try simply continuing. +with_test_prefix "continue" { + test { + # Try stepping the program. Stepping may need to read/write + # registers, unlike continue. + gdb_test "continue" ".*" + + # Try listing threads afterwards. It's probably what the user + # will do after an error. + gdb_test "info threads" ".*" + } +} + +# Try stepping the program. Stepping may go through diferent code +# paths in the target backends. +with_test_prefix "stepi" { + test { + gdb_test "si" ".*" + gdb_test "info threads" ".*" + } +} + +# Try fetching registers explicitly, which should cover the error many +# other commands would trigger. +with_test_prefix "registers" { + test { + gdb_test "flushregs" ".*" + gdb_test "info threads" ".*" + } +} + +# Try only listing threads explicitly, first thing, which is another +# operation GDB may or not decide to do itself and is likely to be +# what a user would try after error too. +with_test_prefix "info threads" { + test { + gdb_test "info threads" ".*" + } +}