diff options
author | Pedro Alves <palves@redhat.com> | 2015-03-11 15:20:31 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2015-07-14 10:55:05 +0100 |
commit | 8ffdba260ca757521c815782a0fe01fedc84849a (patch) | |
tree | 372b799cfaef75ac6604d1b47ed144b64c05a4ad /gdb | |
parent | 586b02a96f744497c8921a558f1c386287849ab0 (diff) | |
download | gdb-8ffdba260ca757521c815782a0fe01fedc84849a.zip gdb-8ffdba260ca757521c815782a0fe01fedc84849a.tar.gz gdb-8ffdba260ca757521c815782a0fe01fedc84849a.tar.bz2 |
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 <palves@redhat.com>
* gdb.base/killed-outside.exp: New file.
* gdb.base/killed-outside.c: New file.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/killed-outside.c | 34 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/killed-outside.exp | 130 |
3 files changed, 169 insertions, 0 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 4f94360..47c1e9b 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-07-14 Pedro Alves <palves@redhat.com> + + * gdb.base/killed-outside.exp: New file. + * gdb.base/killed-outside.c: New file. + 2015-07-10 Jan Kratochvil <jan.kratochvil@redhat.com> * 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 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 <http://www.gnu.org/licenses/>. */ + +#include <sys/types.h> +#include <unistd.h> + +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 <http://www.gnu.org/licenses/>. + +# 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" ".*" + } +} |