From 8ffdba260ca757521c815782a0fe01fedc84849a Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Wed, 11 Mar 2015 15:20:31 +0000 Subject: [PATCH] Add test that exercises the inferior being killed while stopped under GDB 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 previous patches. gdb/testsuite/ChangeLog: 2015-07-14 Pedro Alves * gdb.base/killed-outside.exp: New file. * gdb.base/killed-outside.c: New file. --- gdb/testsuite/ChangeLog | 5 + gdb/testsuite/gdb.base/killed-outside.c | 34 ++++++ gdb/testsuite/gdb.base/killed-outside.exp | 130 ++++++++++++++++++++++ 3 files changed, 169 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/ChangeLog b/gdb/testsuite/ChangeLog index 4f94360f40e..47c1e9b2f04 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-07-14 Pedro Alves + + * gdb.base/killed-outside.exp: New file. + * gdb.base/killed-outside.c: New file. + 2015-07-10 Jan Kratochvil * gdb.asm/asm-source.exp (f at main): Stop at gdbasm_enter. diff --git a/gdb/testsuite/gdb.base/killed-outside.c b/gdb/testsuite/gdb.base/killed-outside.c new file mode 100644 index 00000000000..f0e9edad389 --- /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 00000000000..1e8c0d383e1 --- /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" ".*" + } +} -- 2.30.2