From: Simon Marchi <simark@simark.ca>
To: Martin KOCH <Martin.KOCH@bachmann.info>, gdb-patches@sourceware.org
Subject: Re: [PATCH v2] gdb/remote: fix assertions when attaching in non-stop mode
Date: Wed, 8 Jul 2026 14:57:51 -0400 [thread overview]
Message-ID: <d215ebf7-25b4-49f1-bac8-8f1e0de2baaa@simark.ca> (raw)
In-Reply-To: <20260619092535.2476689-1-Martin.KOCH@bachmann.info>
On 6/19/26 5:25 AM, Martin KOCH wrote:
> When connecting to a remote target in non-stop mode against a
> multi-threaded inferior stopped at raise(SIGSTOP), three internal-error
> assertions can fire in sequence:
>
> remote.c:546: mark_async_event_handler: Assertion 'this->is_async_p ()' failed.
> thread.c:429: set_pending_waitstatus: Assertion 'this->internal_state () ==
> THREAD_INT_STOPPED || ...' failed.
> thread.c:426: set_pending_waitstatus: Assertion '!this->has_pending_waitstatus ()' failed.
>
> The first one is what PR 30630 reports and is fixed with the PR proposed
> by Mikhail Terekhov, but with the fix the two other assertions surface:
>
> * thread.c:429: addressed by reordering set_internal_state / set_state
> to run before set_pending_waitstatus.
> * thread.c:426: addressed by clearing any existing pending wait
> status before installing the new one, when gdbserver delivers
> multiple events for the same thread.
As mentioned in me previous message, the root cause of this is likely a
bug in gdbserver. It's good to make gdb resilient against bugs on the
remote side, but I wouldn't want to merge this in gdb before fixing the
gdbserver bug. Otherwise, it will get forgotten about and it will never
get fixed.
> These assertions are reached through
> remote.c:process_initial_stop_replies, which only runs on the initial
> connection to a remote target, not via GDB's own "attach" command. The
> new test gdb.threads/attach-non-stop-stopped.exp reproduces the issue:
> it starts gdbserver attached to a multi-threaded inferior that is
> already stopped via a pending SIGSTOP, then connects GDB to it in
> non-stop mode. Without this fix the connection trips the assertions
> above; with it, the connection succeeds.
>
> [1] https://sourceware.org/pipermail/gdb-patches/2023-October/202937.html
>
> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30630
> Signed-off-by: Martin KOCH <Martin.KOCH@bachmann.info>
> ---
> gdb/remote.c | 14 ++-
> .../gdb.threads/attach-non-stop-stopped.c | 78 +++++++++++++
> .../gdb.threads/attach-non-stop-stopped.exp | 104 ++++++++++++++++++
> 3 files changed, 191 insertions(+), 5 deletions(-)
> create mode 100644 gdb/testsuite/gdb.threads/attach-non-stop-stopped.c
> create mode 100644 gdb/testsuite/gdb.threads/attach-non-stop-stopped.exp
>
> diff --git a/gdb/remote.c b/gdb/remote.c
> index 2961664cf33..4148301bc6f 100644
> --- a/gdb/remote.c
> +++ b/gdb/remote.c
> @@ -5237,13 +5237,17 @@ remote_target::process_initial_stop_replies (int from_tty)
> ws.set_stopped (sig);
> }
>
> - if (ws.kind () != TARGET_WAITKIND_STOPPED
> - || ws.sig () != GDB_SIGNAL_0)
> - evthread->set_pending_waitstatus (ws);
> -
> set_internal_state (this, event_ptid, THREAD_INT_STOPPED);
> set_state (this, event_ptid, THREAD_STOPPED);
> get_remote_thread_info (evthread)->set_not_resumed ();
> +
> + if (ws.kind () != TARGET_WAITKIND_STOPPED
> + || ws.sig () != GDB_SIGNAL_0)
> + {
Here, add a comment like:
/* This should not happen, but a misbehaving remote could send duplicate
stop replies for a given thread. We arbitrarily keep the last one. */
> + if (evthread->has_pending_waitstatus ())
> + evthread->clear_pending_waitstatus ();
> + evthread->set_pending_waitstatus (ws);
Newline after the if.
> +# GDB survived the connection. As a sanity check, confirm it is
> +# responsive and that all threads are present.
> +for {set attempt 0} {$attempt < 10} {incr attempt} {
> + set thread_count 0
> + gdb_test_multiple "info threads" "" {
> + -re "\r\n\[ *\]+$decimal\[ \t\]+(Thread|LWP|process)\[^\r\n\]*" {
> + incr thread_count
> + exp_continue
> + }
> + -re "$gdb_prompt " {
> + }
> + }
> + if {$thread_count >= $total} {
> + break
> + }
> + sleep 1
> +}
What is the reason for the "attempt" loop and the sleep? Shouldn't all
threads be visible from the start?
Simon
prev parent reply other threads:[~2026-07-08 18:58 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-11 5:36 [PATCH] " Martin KOCH
2026-06-17 3:44 ` Simon Marchi
2026-06-19 9:25 ` [PATCH v2] " Martin KOCH
2026-07-08 18:57 ` Simon Marchi [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d215ebf7-25b4-49f1-bac8-8f1e0de2baaa@simark.ca \
--to=simark@simark.ca \
--cc=Martin.KOCH@bachmann.info \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox