[PATCH v4 29/44] gdb, remote: allow deleting the last thread in inferior in update_thread_list()
Markus Metzger <[email protected]>
| Newsgroups | gmane.comp.gdb.patches |
|---|---|
| Message-ID | <[email protected]> |
We do want to support inferiors without threads, e.g. for GPU inferiors
that may not have any thread when no work is dispatched to that GPU but
that may get new threads again when new work is dispatched.
The test (added in a subsequent patch)
gdb.arch/intelgt-interrupt-exited-thread.exp
resumes a single GPU thread with scheduler-locking on and then interrupts
the target with C-c. The GPU thread meanwhile finished its dispatch, so
when the target interrupts the device, it does not respond.
In response to vCtrlC, gdbserver-intelgt sends
%Stop:N
to indicate that nothing is running on the device anymore. GDB receives
the notification. In handle_no_resumed(), GDB updates the thread list.
In this scenario, the thread that GDB had resumed was the last thread on
the device, so the thread list is now empty. If we're not deleting that
thread, handle_no_resumed() will ignore the event since it found a resumed
thread, and we're stuck.
To the user, it would appear as if GDB were hanging. Interrupting the
target with C-c does not have any effect and there is no way to get the
prompt back.
This patch causes regressions in
gdb.replay/missing.thread.exp
When the replay log is updated to remove all threads like this
w $qXfer:threads:read::0,1000#92
r $l<threads>\n</threads>\n#68<Timeout: 0 seconds>
GDB removes the thread and no longer interacts with it, so replay fails at
the subsequent
w $QThreadOptions;0#00
r $OK#9a<Timeout: 0 seconds>
This patch removes that part of the test.
---
gdb/remote.c | 20 ---------------
gdb/testsuite/gdb.replay/missing-thread.exp | 28 +++------------------
2 files changed, 3 insertions(+), 45 deletions(-)
diff --git a/gdb/remote.c b/gdb/remote.c
index 5721e791612..10bceb2c798 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -4479,18 +4479,6 @@ remote_target::remote_get_threads_with_qthreadinfo (threads_listing_context *con
return 0;
}
-/* Return true if INF only has one non-exited thread. */
-
-static bool
-has_single_non_exited_thread (inferior *inf)
-{
- int count = 0;
- for (thread_info &tp ATTRIBUTE_UNUSED : inf->non_exited_threads ())
- if (++count > 1)
- break;
- return count == 1;
-}
-
/* Implement the to_update_thread_list function for the remote
targets. */
@@ -4526,14 +4514,6 @@ remote_target::update_thread_list ()
for (thread_info &tp : all_threads_safe (this))
if (!context.contains_thread (tp.ptid))
{
- /* Do not remove the thread if it is the last thread in
- the inferior. This situation happens when we have a
- pending exit process status to process. Otherwise we
- may end up with a seemingly live inferior (i.e. pid
- != 0) that has no threads. */
- if (has_single_non_exited_thread (tp.inf))
- continue;
-
/* Do not remove the thread if we've requested to be
notified of its exit. For example, the thread may be
displaced stepping, infrun will need to handle the
diff --git a/gdb/testsuite/gdb.replay/missing-thread.exp b/gdb/testsuite/gdb.replay/missing-thread.exp
index 23bbddac556..a27a0181c7f 100644
--- a/gdb/testsuite/gdb.replay/missing-thread.exp
+++ b/gdb/testsuite/gdb.replay/missing-thread.exp
@@ -83,10 +83,7 @@ proc_with_prefix record_initial_logfile { log_filename } {
# The line to be modified is the last <threads>...</threads> line, this is
# the reply from the remote that indicates the thread list. It is expected
# that the thread list will contain two threads.
-#
-# When DROP_BOTH is true then both threads will be removed from the modified
-# line. Otherwise, only the second thread is removed.
-proc update_replay_log { in_filename out_filename drop_both } {
+proc update_replay_log { in_filename out_filename } {
# Read IN_FILENAME into a list.
set fd [open $in_filename]
set data [read $fd]
@@ -108,11 +105,7 @@ proc update_replay_log { in_filename out_filename drop_both } {
set fixed_log false
if {[regexp "^(r .*<threads>\\\\n)(<thread id.*/>\\\\n)(<thread id.*/>\\\\n)(</threads>.*)$" $line \
match part1 part2 part3 part4]} {
- if { $drop_both } {
- set line $part1$part4
- } else {
- set line $part1$part2$part4
- }
+ set line $part1$part2$part4
set lines [lreplace $lines $idx $idx $line]
set fixed_log true
}
@@ -192,18 +185,13 @@ proc run_test { non_stop } {
# The replay log is placed in 'replay.log'.
set remote_log [standard_output_file replay${suffix}.log]
set missing_1_log [standard_output_file replay-missing-1${suffix}.log]
- set missing_2_log [standard_output_file replay-missing-2${suffix}.log]
record_initial_logfile $remote_log
- if { ![update_replay_log $remote_log $missing_1_log false] } {
+ if { ![update_replay_log $remote_log $missing_1_log] } {
fail "couldn't update remote replay log (drop 1 case)"
}
- if { ![update_replay_log $remote_log $missing_2_log true] } {
- fail "couldn't update remote replay log (drop 2 case)"
- }
-
with_test_prefix "with unmodified log" {
# Replay with the unmodified log. This confirms that we can replay this
# scenario correctly.
@@ -216,16 +204,6 @@ proc run_test { non_stop } {
# error when the inferior stops.
replay_with_log $missing_1_log true $non_stop
}
-
- with_test_prefix "missing 2 threads log" {
- # When we drop both threads from the <threads> reply, GDB doesn't
- # actually remove both threads from the inferior; an inferior must
- # always have at least one thread. So in this case, as the primary
- # thread is first, GDB drops this, then retains the second thread, which
- # is the one we're stopping in, and so, we don't expect to see the error
- # in this case.
- replay_with_log $missing_2_log false $non_stop
- }
}
# Run the test twice, with non-stop on and off.
--
2.43.0
________________________________________
Intel Deutschland GmbH
Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 (89) 99143-0
www.intel.de
Managing Directors: Candice Moore, Jeffrey Schneiderman, Ramachandran Sitaraman
Chairperson of the Supervisory Board: Sonja Pierer
Registered Seat: Munich Commercial Register B: Amtsgericht Munich HRB 186928
This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.