aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2015-03-11 15:20:31 +0000
committerPedro Alves <palves@redhat.com>2015-07-14 10:55:05 +0100
commit8ffdba260ca757521c815782a0fe01fedc84849a (patch)
tree372b799cfaef75ac6604d1b47ed144b64c05a4ad
parent586b02a96f744497c8921a558f1c386287849ab0 (diff)
downloadgdb-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.
-rw-r--r--gdb/testsuite/ChangeLog5
-rw-r--r--gdb/testsuite/gdb.base/killed-outside.c34
-rw-r--r--gdb/testsuite/gdb.base/killed-outside.exp130
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" ".*"
+ }
+}