diff --git a/gdb/infrun.c b/gdb/infrun.c
index 3e846f8..a722da5 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -4749,7 +4749,12 @@
/* The thread may be not executing, but still be
resumed with a pending status to process. */
- t->resumed = false;
+ if (t->suspend.waitstatus.kind == TARGET_WAITKIND_SIGNALLED
+ && t->suspend.waitstatus.value.sig == GDB_SIGNAL_KILL
+ && t->suspend.waitstatus_pending_p)
+ ;
+ else
+ t->resumed = false;
}
}
@@ -4772,7 +4777,15 @@
target_pid_to_str (event.ptid).c_str ());
}
- if (event.ws.kind == TARGET_WAITKIND_NO_RESUMED
+ if (event.ws.kind == TARGET_WAITKIND_SIGNALLED
+ && event.ws.value.sig == GDB_SIGNAL_KILL)
+ {
+ thread_info *t = find_thread_ptid (event.target, event.ptid);
+ save_waitstatus (t, &event.ws);
+ t->resumed = true;
+ t->executing = false;
+ }
+ else if (event.ws.kind == TARGET_WAITKIND_NO_RESUMED
|| event.ws.kind == TARGET_WAITKIND_THREAD_EXITED
|| event.ws.kind == TARGET_WAITKIND_EXITED
|| event.ws.kind == TARGET_WAITKIND_SIGNALLED)
diff --git a/gdb/testsuite/gdb.threads/kill-in-stop-all-threads.c b/gdb/testsuite/gdb.threads/kill-in-stop-all-threads.c
new file mode 100644
index 0000000..cddbd4d
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/kill-in-stop-all-threads.c
@@ -0,0 +1,42 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2020 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
+#include
+
+static void *
+fun (void *dummy)
+{
+ raise (SIGINT);
+ while (1)
+ sleep (1);
+
+ return NULL;
+}
+
+int
+main (void)
+{
+ pthread_t thread;
+ pthread_create (&thread, NULL, fun, NULL);
+
+ while (1)
+ sleep (1);
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.threads/kill-in-stop-all-threads.exp b/gdb/testsuite/gdb.threads/kill-in-stop-all-threads.exp
new file mode 100644
index 0000000..2df509f
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/kill-in-stop-all-threads.exp
@@ -0,0 +1,125 @@
+# Copyright 2020 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 . */
+
+# This test-case starts gdb with a $binfile inferior, which sends a SIGINT to
+# itself. Then when gdb handles the SIGINT and starts executing
+# stop_all_threads, the inferior is killed by a SIGKILL.
+#
+# In order to time the SIGKILL, the gdb itself is run using another gdb, which
+# allows us to set a breakpoint on stop_all_threads. So, we have the following
+# hierarchy:
+# - master gdb
+# - inferior gdb
+# - $binfile
+#
+# This setup make this a non-standard test-case.
+#
+
+standard_testfile
+
+if {[build_executable "failed to build" $testfile $srcfile \
+ {debug pthreads}] == -1} {
+ return -1
+}
+
+# Setup master gdb, with inferior gdb as executable.
+clean_restart $GDB
+
+# Set master gdb to have a different prompt, to make it easier to distinguish
+# between prompts of master gdb and inferior gdb.
+set saved_gdb_prompt $gdb_prompt
+set master_gdb_prompt "\\(master-gdb\\)"
+set gdb_prompt $master_gdb_prompt
+gdb_test_no_output "set prompt $master_gdb_prompt "
+
+# Set the arguments for the inferior gdb.
+gdb_test_no_output "set args $INTERNAL_GDBFLAGS $GDBFLAGS $binfile"
+
+# Run to main in master gdb.
+if ![runto_main] then {
+ fail "can't run to main"
+ return 0
+}
+
+# Set a breakpoint for the inferior gdb in master gdb.
+if {[gdb_breakpoint "stop_all_threads" no-message] != 1 } {
+ # If we cannot set this breakpoint, there no point in trying further.
+ # Bail out.
+ return -1
+}
+
+# Continue from main in master gdb to initial inferior gdb prompt.
+set gdb_prompt $saved_gdb_prompt
+gdb_test "continue" "Continuing\..*Reading symbols from.*" \
+ "continue from gdb main"
+
+# Start $binfile
+set gdb_prompt $master_gdb_prompt
+gdb_test "start" "Starting program.*Breakpoint 2, stop_all_threads \\(\\).*" \
+ "start inferior"
+
+# We run into stop_all_threads breakpoint in master gdb here, but it's too
+# early, continue to inferior gdb prompt.
+set gdb_prompt $saved_gdb_prompt
+gdb_continue_to_breakpoint "continue past stop_all_threads bp" ".*$srcfile:.*"
+
+# Get the pid of the $binfile process
+set pid -1
+gdb_test_multiple "info inferior 1" "get inferior pid" {
+ -re -wrap "process (\[0-9\]*).*" {
+ set pid $expect_out(1,string)
+ pass $gdb_test_name
+ }
+}
+if { $pid == -1 } {
+ return -1
+}
+
+# Continue $binfile. The $binfile will then trigger SIGINT, which will
+# trigger stop_all_threads in inferior gdb, which will cause the breakpoint
+# to hit in master gdb.
+set gdb_prompt $master_gdb_prompt
+gdb_continue_to_breakpoint "continue to stop_all_threads bp" ".*infrun.c:.*"
+
+# Kill inferior in master gdb, while we're at the start of stop_all_threads in
+# inferior gdb.
+gdb_test_no_output "shell kill -9 $pid"
+
+# Continue from master gdb prompt to inferior gdb prompt.
+set gdb_prompt $saved_gdb_prompt
+gdb_test_multiple "continue" "continue to raise sigint" {
+ -re "warning: unable to open /proc file" {
+ # This warning is the first sign of trouble before we start hanging.
+ # Fail and bail out now, instead of waiting for a timeout.
+ fail $gdb_test_name
+ return -1
+ }
+ -re -wrap "Continuing\.\[\r\n\]+Thread \[0-9\]+ received signal SIGINT, Interrupt\..*" {
+ pass $gdb_test_name
+ }
+}
+
+# Check that the SIGKILL of $binfile is reported by inferior gdb.
+set killed_msg [multi_line "Program terminated with signal SIGKILL, Killed\." \
+ "The program no longer exists\."]
+gdb_test "continue" "Continuing\.\[\r\n\]+$killed_msg" "continue to inferior exit"
+
+# Check that inferior gdb exits normally
+set gdb_prompt $master_gdb_prompt
+gdb_test "quit" "$inferior_exited_re normally\\\]"
+
+# Restore gdb prompt in master gdb.
+set gdb_prompt $saved_gdb_prompt
+gdb_test_no_output "set prompt $saved_gdb_prompt "