From 64d38fdd9956aefd1f0fbeb7e1d2774e71c0a9b8 Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Thu, 25 Feb 2021 08:27:09 +0100 Subject: [PATCH] Fix initial thread state of non-threaded remote targets This change fixes the initial state of the main thread of remote targets which have no concept of threading. Such targets are treated as single-threaded by gdb, and this single thread needs to be initially set to the "resumed" state, in the same manner as threads in thread-aware remote targets (see remote.c, remote_target::remote_add_thread). Without this fix, the following assert was triggered on thread- unaware remote targets: remote_target::select_thread_for_ambiguous_stop_reply(const target_waitstatus*): Assertion `first_resumed_thread != nullptr' failed. The bug can be reproduced using gdbserver * by disabling packets 'T' and 'qThreadInfo', or * by disabling all thread-related packets. The test suite has been updated to include these two scenarios, see gdb.server/stop-reply-no-thread.exp. Change-Id: I2c39c9de17e8d6922a8c1b9e259eb316a554a43d --- gdb/ChangeLog | 10 ++++++++++ gdb/remote.c | 13 +++++++++---- gdb/testsuite/ChangeLog | 7 +++++++ gdb/testsuite/gdb.server/stop-reply-no-thread.exp | 10 ++++++++++ 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 27b0e0cfec0..74e0dee1b0f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2021-02-25 Jan Matyas + + PR gdb/26819 + * remote.c (remote_target::start_remote): Ensure the single + thread, automatically added for remote targets without the + concept of threading, is initially in set to the "resumed" + state. + * remote.c (remote_target::add_current_inferior_and_thread): + Add return value - return the main thread. + 2021-02-25 Jan Vrany * gdb/mi/mi-interp.c (mi_traceframe_changed): Remove trailing \n from output. diff --git a/gdb/remote.c b/gdb/remote.c index 2c85bdcffbc..ae15f416153 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -741,7 +741,7 @@ public: /* Remote specific methods. */ int remote_resume_with_vcont (ptid_t ptid, int step, gdb_signal siggnal); - void add_current_inferior_and_thread (const char *wait_status); + thread_info *add_current_inferior_and_thread (const char *wait_status); ptid_t wait_ns (ptid_t ptid, struct target_waitstatus *status, target_wait_flags options); @@ -4409,9 +4409,11 @@ remote_target::get_current_thread (const char *wait_status) whose response is a stop reply from which we can also try extracting the thread. If the target doesn't support the explicit qC query, we infer the current thread from that stop reply, passed - in in WAIT_STATUS, which may be NULL. */ + in in WAIT_STATUS, which may be NULL. -void + The function returns pointer to the main thread of the inferior. */ + +thread_info * remote_target::add_current_inferior_and_thread (const char *wait_status) { struct remote_state *rs = get_remote_state (); @@ -4445,6 +4447,8 @@ remote_target::add_current_inferior_and_thread (const char *wait_status) yet. */ thread_info *tp = add_thread_silent (this, curr_ptid); switch_to_thread_no_regs (tp); + + return tp; } /* Print info about a thread that was found already stopped on @@ -4800,7 +4804,8 @@ remote_target::start_remote (int from_tty, int extended_p) /* Target has no concept of threads at all. GDB treats non-threaded target as single-threaded; add a main thread. */ - add_current_inferior_and_thread (wait_status); + thread_info *tp = add_current_inferior_and_thread (wait_status); + get_remote_thread_info (tp)->set_resumed (); } else { diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 46d27a1b52f..f2c142e6b94 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2021-02-25 Jan Matyas + + PR gdb/26819 + * gdb.server/stop-reply-no-thread.exp: Add two test + scenarios that cover remote targets which do not have + the concept of threads. + 2021-02-25 Andrew Burgess * gdb.fortran/associated.exp: Add missing '-wrap' argument. diff --git a/gdb/testsuite/gdb.server/stop-reply-no-thread.exp b/gdb/testsuite/gdb.server/stop-reply-no-thread.exp index 68bf42ac1a0..823bdf894c0 100644 --- a/gdb/testsuite/gdb.server/stop-reply-no-thread.exp +++ b/gdb/testsuite/gdb.server/stop-reply-no-thread.exp @@ -112,3 +112,13 @@ foreach_with_prefix to_disable { "" Tthread T } { run_test $to_disable $t_nonstop } } + +# Regression for PR gdb/26819: Cover the case when GDBserver does not report +# any threads (i.e. the remote target has no concept of threads). +# +# Scenario 1: Disable 'T' and 'qfThreadInfo' packets +# Scenario 2: Disable all threading packets +foreach_with_prefix to_disable { "T,qfThreadInfo" "threads" } { + # Non-stop mode not applicable - off. + run_test $to_disable off +} -- 2.30.2