* [PATCH v4 01/11] gdb, record: fix assertion when remote target is set to non-stop
2026-07-14 9:21 [PATCH v4 00/11] Add AlwaysNonStop remote protocol extension Mohamed Bouhaouel
@ 2026-07-14 9:21 ` Mohamed Bouhaouel
2026-07-14 9:21 ` [PATCH v4 02/11] gdb, remote: fix assertion on reconnect to non-stop target Mohamed Bouhaouel
` (9 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Mohamed Bouhaouel @ 2026-07-14 9:21 UTC (permalink / raw)
To: gdb-patches; +Cc: markus.t.metzger, stephan.rohr, eliz, aburgess, pedro
From: Markus Metzger <markus.t.metzger@intel.com>
When forcing the remote target to non-stop via 'maint set target-non-stop
on', reverse tests start failing with
(gdb) .../gdb/remote.c:7561: internal-error: resume: Assertion `scope_ptid == inferior_ptid' failed.
This is caused by the record-full target doing one additional step after
receiving a single-step trap event. That additional step is done on the
wait ptid instead of on the event ptid. Fix it.
Reproducible when running gdb.reverse/*.exp, on native-gdbserver or
native-extended-gdbserver with target-non-stop enabled.
export GDBFLAGS="-iex \"maint set target-non-stop on\""
make check TESTS="gdb.reverse/*.exp" \
RUNTESTFLAGS="--target_board=native-gdbserver GDBFLAGS='$GDBFLAGS'"
---
gdb/record-full.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/gdb/record-full.c b/gdb/record-full.c
index aa451c05a5d..6607dc4c1ba 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -1298,7 +1298,8 @@ record_full_wait_1 (struct target_ops *ops,
"Process record: record_full_wait "
"issuing one more step in the "
"target beneath\n");
- ops->beneath ()->resume (ptid, step, GDB_SIGNAL_0);
+ ops->beneath ()->resume (inferior_ptid, step,
+ GDB_SIGNAL_0);
proc_target->commit_resumed_state = true;
proc_target->commit_resumed ();
proc_target->commit_resumed_state = false;
--
2.43.0
Intel Deutschland GmbH
Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 89 991 430, www.intel.de
Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell
Chairperson of the Supervisory Board: Nicole Lau
Registered Seat: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH v4 02/11] gdb, remote: fix assertion on reconnect to non-stop target
2026-07-14 9:21 [PATCH v4 00/11] Add AlwaysNonStop remote protocol extension Mohamed Bouhaouel
2026-07-14 9:21 ` [PATCH v4 01/11] gdb, record: fix assertion when remote target is set to non-stop Mohamed Bouhaouel
@ 2026-07-14 9:21 ` Mohamed Bouhaouel
2026-07-14 9:21 ` [PATCH v4 03/11] gdb, remote: fix async handler " Mohamed Bouhaouel
` (8 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Mohamed Bouhaouel @ 2026-07-14 9:21 UTC (permalink / raw)
To: gdb-patches; +Cc: markus.t.metzger, stephan.rohr, eliz, aburgess, pedro
From: "Bouhaouel, Mohamed" <mohamed.bouhaouel@intel.com>
When reconnecting to a non-stop remote target, threads may retain stale
internal state from the previous connection (e.g., THREAD_INT_RUNNING).
This causes an assertion failure in
thread_info::set_pending_waitstatus(), which requires the thread to be
in THREAD_INT_STOPPED or THREAD_INT_RESUMED_PENDING_STATUS state.
Fix by setting thread's states before calling set_pending_waitstatus ()
in process_initial_stop_replies ().
Scenario:
- Connect to non-stop remote target with running threads.
- Disconnect (threads remain in THREAD_INT_RUNNING state).
- Reconnect to same target.
- process_initial_stop_replies() processes stop events.
- Assertion fails when trying to set pending waitstatus on thread still
marked as THREAD_INT_RUNNING.
Reproducible when running gdb.server/reconnect-ctrl-c.exp, on
native-gdbserver or native-extended-gdbserver with target-non-stop
enabled.
export GDBFLAGS="-iex \"maint set target-non-stop on\""
make check TESTS="gdb.server/reconnect-ctrl-c.exp" \
RUNTESTFLAGS="--target_board=native-gdbserver GDBFLAGS='$GDBFLAGS'"
---
gdb/remote.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/gdb/remote.c b/gdb/remote.c
index 194c4cbd9bb..7022e58abab 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -5177,12 +5177,13 @@ remote_target::process_initial_stop_replies (int from_tty)
ws.set_stopped (sig);
}
+ set_internal_state (this, event_ptid, THREAD_INT_STOPPED);
+ set_state (this, event_ptid, THREAD_STOPPED);
+
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 ();
}
--
2.43.0
Intel Deutschland GmbH
Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 89 991 430, www.intel.de
Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell
Chairperson of the Supervisory Board: Nicole Lau
Registered Seat: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH v4 03/11] gdb, remote: fix async handler assertion on reconnect to non-stop target
2026-07-14 9:21 [PATCH v4 00/11] Add AlwaysNonStop remote protocol extension Mohamed Bouhaouel
2026-07-14 9:21 ` [PATCH v4 01/11] gdb, record: fix assertion when remote target is set to non-stop Mohamed Bouhaouel
2026-07-14 9:21 ` [PATCH v4 02/11] gdb, remote: fix assertion on reconnect to non-stop target Mohamed Bouhaouel
@ 2026-07-14 9:21 ` Mohamed Bouhaouel
2026-07-14 9:21 ` [PATCH v4 04/11] gdb, remote: fix "info program" after " Mohamed Bouhaouel
` (7 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Mohamed Bouhaouel @ 2026-07-14 9:21 UTC (permalink / raw)
To: gdb-patches; +Cc: markus.t.metzger, stephan.rohr, eliz, aburgess, pedro
From: "Bouhaouel, Mohamed" <mohamed.bouhaouel@intel.com>
When reconnecting to a non-stop remote target during
process_initial_stop_replies (), the code attempts to mark an async event
handler before async mode is enabled. This causes an assertion failure
in remote_state::mark_async_event_handler (), which requires the serial
connection to be in async mode (is_async_p () == true).
Fix by changing the condition in queued_stop_reply () from
target_can_async_p () to target_is_async_p (), matching the pattern used
in push_stop_reply (). When async mode is later enabled, the event
handler will be marked then.
Scenario:
- Connect to non-stop remote target.
- Thread receives signal (e.g., SIGUSR1) and stops.
- Disconnect and reconnect.
- Assertion fails because mark_async_event_handler () requires
is_async_p ().
Reproducible when running gdb.threads/reconnect-signal.exp, on
native-gdbserver or native-extended-gdbserver with target-non-stop
enabled.
export GDBFLAGS="-iex \"maint set target-non-stop on\""
make check TESTS="gdb.threads/reconnect-signal.exp" \
RUNTESTFLAGS="--target_board=native-gdbserver GDBFLAGS='$GDBFLAGS'"
---
gdb/remote.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gdb/remote.c b/gdb/remote.c
index 7022e58abab..c5c2814aa55 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -8325,7 +8325,7 @@ remote_target::queued_stop_reply (ptid_t ptid)
remote_state *rs = get_remote_state ();
stop_reply_up r = remote_notif_remove_queued_reply (ptid);
- if (!rs->stop_reply_queue.empty () && target_can_async_p ())
+ if (!rs->stop_reply_queue.empty () && target_is_async_p ())
{
/* There's still at least an event left. */
rs->mark_async_event_handler ();
--
2.43.0
Intel Deutschland GmbH
Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 89 991 430, www.intel.de
Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell
Chairperson of the Supervisory Board: Nicole Lau
Registered Seat: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH v4 04/11] gdb, remote: fix "info program" after reconnect to non-stop target
2026-07-14 9:21 [PATCH v4 00/11] Add AlwaysNonStop remote protocol extension Mohamed Bouhaouel
` (2 preceding siblings ...)
2026-07-14 9:21 ` [PATCH v4 03/11] gdb, remote: fix async handler " Mohamed Bouhaouel
@ 2026-07-14 9:21 ` Mohamed Bouhaouel
2026-07-14 9:21 ` [PATCH v4 05/11] gdb, remote: fix crash when accessing removed events Mohamed Bouhaouel
` (6 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Mohamed Bouhaouel @ 2026-07-14 9:21 UTC (permalink / raw)
To: gdb-patches; +Cc: markus.t.metzger, stephan.rohr, eliz, aburgess, pedro
From: "Bouhaouel, Mohamed" <mohamed.bouhaouel@intel.com>
After reconnecting to a non-stop remote target that has stopped threads,
"info program" incorrectly reports "The program being debugged is not
being run" instead of showing the stop information. This happens because
the previous_thread global is not updated when processing initial stop
replies.
Fix by calling update_previous_thread () after set_last_target_status ()
in print_one_stopped_thread ().
Scenario:
- Connect to non-stop remote target
- Thread receives signal (e.g., SIGUSR1) and stops
- Disconnect and reconnect
- "info program" reports "not being run" (FAIL)
Reproducible when running gdb.threads/reconnect-signal.exp, on
native-gdbserver or native-extended-gdbserver with target-non-stop
enabled.
export GDBFLAGS="-iex \"maint set target-non-stop on\""
make check TESTS="gdb.threads/reconnect-signal.exp" \
RUNTESTFLAGS="--target_board=native-gdbserver GDBFLAGS='$GDBFLAGS'"
---
gdb/remote.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/gdb/remote.c b/gdb/remote.c
index c5c2814aa55..02fefdab067 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -5105,6 +5105,7 @@ remote_target::print_one_stopped_thread (thread_info *thread)
/* For "info program". */
set_last_target_status (this, thread->ptid, ws);
+ update_previous_thread ();
if (ws.kind () == TARGET_WAITKIND_STOPPED)
{
--
2.43.0
Intel Deutschland GmbH
Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 89 991 430, www.intel.de
Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell
Chairperson of the Supervisory Board: Nicole Lau
Registered Seat: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH v4 05/11] gdb, remote: fix crash when accessing removed events
2026-07-14 9:21 [PATCH v4 00/11] Add AlwaysNonStop remote protocol extension Mohamed Bouhaouel
` (3 preceding siblings ...)
2026-07-14 9:21 ` [PATCH v4 04/11] gdb, remote: fix "info program" after " Mohamed Bouhaouel
@ 2026-07-14 9:21 ` Mohamed Bouhaouel
2026-07-14 9:21 ` [PATCH v4 06/11] gdb, remote: fix ptid matching for process-wide stop events Mohamed Bouhaouel
` (5 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Mohamed Bouhaouel @ 2026-07-14 9:21 UTC (permalink / raw)
To: gdb-patches; +Cc: markus.t.metzger, stephan.rohr, eliz, aburgess, pedro
From: "Bouhaouel, Mohamed" <mohamed.bouhaouel@intel.com>
Dereferencing events after calling std::remove_if causes GDB to crash
because the matching unique_ptrs have been moved from and are null.
Fix by logging events in std::remove_if.
The bug is visible by inspection; reproducing it requires
discard_pending_stop_replies to be called with matching entries in the
queue and remote debug logging enabled.
---
gdb/remote.c | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/gdb/remote.c b/gdb/remote.c
index 02fefdab067..b27b1a1b6c0 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -8254,17 +8254,20 @@ remote_target::discard_pending_stop_replies (struct inferior *inf)
/* Discard the stop replies we have already pulled with
vStopped. */
- auto iter = std::remove_if (rs->stop_reply_queue.begin (),
- rs->stop_reply_queue.end (),
- [=] (const stop_reply_up &event)
- {
- return event->ptid.pid () == inf->pid;
- });
- for (auto it = iter; it != rs->stop_reply_queue.end (); ++it)
- remote_debug_printf
- ("discarding queued stop reply: ptid: %s, ws: %s\n",
- (*it)->ptid.to_string().c_str(),
- (*it)->ws.to_string ().c_str ());
+ auto iter
+ = std::remove_if (rs->stop_reply_queue.begin (),
+ rs->stop_reply_queue.end (),
+ [=] (const stop_reply_up &event)
+ {
+ if (event->ptid.pid () != inf->pid)
+ return false;
+
+ remote_debug_printf
+ ("discarding queued stop reply: ptid: %s, ws: %s\n",
+ event->ptid.to_string ().c_str (),
+ event->ws.to_string ().c_str ());
+ return true;
+ });
rs->stop_reply_queue.erase (iter, rs->stop_reply_queue.end ());
}
--
2.43.0
Intel Deutschland GmbH
Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 89 991 430, www.intel.de
Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell
Chairperson of the Supervisory Board: Nicole Lau
Registered Seat: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH v4 06/11] gdb, remote: fix ptid matching for process-wide stop events
2026-07-14 9:21 [PATCH v4 00/11] Add AlwaysNonStop remote protocol extension Mohamed Bouhaouel
` (4 preceding siblings ...)
2026-07-14 9:21 ` [PATCH v4 05/11] gdb, remote: fix crash when accessing removed events Mohamed Bouhaouel
@ 2026-07-14 9:21 ` Mohamed Bouhaouel
2026-07-14 9:21 ` [PATCH v4 07/11] gdb, dap: fix DAP events if no thread is selected Mohamed Bouhaouel
` (4 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Mohamed Bouhaouel @ 2026-07-14 9:21 UTC (permalink / raw)
To: gdb-patches; +Cc: markus.t.metzger, stephan.rohr, eliz, aburgess, pedro
From: "Rohr, Stephan" <stephan.rohr@intel.com>
If an inferior call results in a process event for a non-stop remote
target, GDB does not properly handle the event but is hanging.
Because GDB is evaluating a breakpoint condition, the corresponding
inferior call is evaluated w.r.t. the ptid of the current thread.
gdbserver sends a process exit event; the event is not matched by the
thread PTID and GDB hangs.
Fix this by matching a process event in 'stop_reply_queue' if there is
no matching thread event. This ensures a thread event is prioritized
if both a thread event and a process event are queued and preserves the
current behavior.
Reproducible when running gdb.base/exit-in-condition.exp, on
native-extended-gdbserver with target-non-stop enabled.
export GDBFLAGS="-iex \"maint set target-non-stop on\""
make check TESTS="gdb.base/exit-in-condition.exp" \
RUNTESTFLAGS="--target_board=native-extended-gdbserver GDBFLAGS='$GDBFLAGS'"
---
gdb/remote.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/gdb/remote.c b/gdb/remote.c
index b27b1a1b6c0..b1bc1283b9a 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -8303,6 +8303,20 @@ remote_target::remote_notif_remove_queued_reply (ptid_t ptid)
{
return event->ptid.matches (ptid);
});
+
+ /* Match process events if PTID is a thread and there is no matching event
+ queued. Prioritize thread events to preserve the existing behavior. */
+ if (iter == rs->stop_reply_queue.end ()
+ && ptid != minus_one_ptid
+ && !ptid.is_pid ())
+ iter = std::find_if (rs->stop_reply_queue.begin (),
+ rs->stop_reply_queue.end (),
+ [=] (const stop_reply_up &event)
+ {
+ return (event->ptid.is_pid ()
+ && event->ptid.pid () == ptid.pid ());
+ });
+
stop_reply_up result;
if (iter != rs->stop_reply_queue.end ())
{
--
2.43.0
Intel Deutschland GmbH
Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 89 991 430, www.intel.de
Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell
Chairperson of the Supervisory Board: Nicole Lau
Registered Seat: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH v4 07/11] gdb, dap: fix DAP events if no thread is selected
2026-07-14 9:21 [PATCH v4 00/11] Add AlwaysNonStop remote protocol extension Mohamed Bouhaouel
` (5 preceding siblings ...)
2026-07-14 9:21 ` [PATCH v4 06/11] gdb, remote: fix ptid matching for process-wide stop events Mohamed Bouhaouel
@ 2026-07-14 9:21 ` Mohamed Bouhaouel
2026-07-14 9:21 ` [PATCH v4 08/11] gdb, testsuite: handle async close in monitor-exit-quit.exp Mohamed Bouhaouel
` (3 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Mohamed Bouhaouel @ 2026-07-14 9:21 UTC (permalink / raw)
To: gdb-patches; +Cc: markus.t.metzger, stephan.rohr, eliz, aburgess, pedro
From: "Rohr, Stephan" <stephan.rohr@intel.com>
The DAP protocol requires a thread-id for a continue event. It is
optional for the stopped event. If we force the remote target to run in
non-stop mode, i.e., "-iex maint set target-non-stop on", GDB does not
have a thread selected. Default to '0' for continue events in this
case. Omit the 'threadID' for stopped events if no thread is selected.
Reproducible when running gdb.dap/remote-dap.exp on unix with
target-non-stop enabled.
export GDBFLAGS="-iex \"maint set target-non-stop on\""
make check TESTS="gdb.dap/remote-dap.exp" \
RUNTESTFLAGS="--target_board=unix GDBFLAGS='$GDBFLAGS'"
---
gdb/python/lib/gdb/dap/events.py | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/gdb/python/lib/gdb/dap/events.py b/gdb/python/lib/gdb/dap/events.py
index 27e3b5ab8bc..85e672b4c9e 100644
--- a/gdb/python/lib/gdb/dap/events.py
+++ b/gdb/python/lib/gdb/dap/events.py
@@ -138,10 +138,14 @@ def _cont(event):
log("_suppress_cont case")
_suppress_cont = False
else:
+ thread = gdb.selected_thread()
+
+ # We may not have a selected thread if the target is running in
+ # non-stop mode. Default to '0' in this case.
send_event(
"continued",
{
- "threadId": gdb.selected_thread().global_num,
+ "threadId": thread.global_num if thread else 0,
"allThreadsContinued": True,
},
)
@@ -213,9 +217,11 @@ def _on_stop(event):
if hasattr(event, "details"):
log(" details: " + repr(event.details))
obj = {
- "threadId": gdb.selected_thread().global_num,
"allThreadsStopped": True,
}
+ # The thread-id parameter is optional for stopped events.
+ if gdb.selected_thread():
+ obj["threadId"] = gdb.selected_thread().global_num
if isinstance(event, gdb.BreakpointEvent):
obj["hitBreakpointIds"] = [x.number for x in event.breakpoints]
if hasattr(event, "details") and "finish-value" in event.details:
@@ -266,11 +272,14 @@ def _on_inferior_call(event):
if not _infcall_was_running and inferior_running:
inferior_running = False
obj = {
- "threadId": gdb.selected_thread().global_num,
"allThreadsStopped": True,
# DAP says any string is ok.
"reason": "function call",
}
+ # The thread-id parameter is optional for stopped events.
+ if gdb.selected_thread():
+ obj["threadId"] = gdb.selected_thread().global_num
+
global _expected_pause
_expected_pause = False
send_event("stopped", obj)
--
2.43.0
Intel Deutschland GmbH
Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 89 991 430, www.intel.de
Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell
Chairperson of the Supervisory Board: Nicole Lau
Registered Seat: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH v4 08/11] gdb, testsuite: handle async close in monitor-exit-quit.exp
2026-07-14 9:21 [PATCH v4 00/11] Add AlwaysNonStop remote protocol extension Mohamed Bouhaouel
` (6 preceding siblings ...)
2026-07-14 9:21 ` [PATCH v4 07/11] gdb, dap: fix DAP events if no thread is selected Mohamed Bouhaouel
@ 2026-07-14 9:21 ` Mohamed Bouhaouel
2026-07-14 9:21 ` [PATCH v4 09/11] gdb, testsuite: update attach-deleted-exec.exp to handle async messages Mohamed Bouhaouel
` (2 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Mohamed Bouhaouel @ 2026-07-14 9:21 UTC (permalink / raw)
To: gdb-patches; +Cc: markus.t.metzger, stephan.rohr, eliz, aburgess, pedro
From: "Bouhaouel, Mohamed" <mohamed.bouhaouel@intel.com>
With non-stop remote targets, the "Remote connection closed"
notification arrives asynchronously after "monitor exit" and may appear
while processing the quit command, causing test failures.
Fix by handling the async notification in both the monitor exit command
(for early delivery) and the quit sequence (for late delivery).
Reproducible when running gdb.server/monitor-exit-quit.exp, on
native-gdbserver or native-extended-gdbserver with target-non-stop
enabled.
export GDBFLAGS="-iex \"maint set target-non-stop on\""
make check TESTS="gdb.server/monitor-exit-quit.exp" \
RUNTESTFLAGS="--target_board=native-gdbserver GDBFLAGS='$GDBFLAGS'"
---
.../gdb.server/monitor-exit-quit.exp | 21 ++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/gdb/testsuite/gdb.server/monitor-exit-quit.exp b/gdb/testsuite/gdb.server/monitor-exit-quit.exp
index cb90169ef0c..46c11fe9462 100644
--- a/gdb/testsuite/gdb.server/monitor-exit-quit.exp
+++ b/gdb/testsuite/gdb.server/monitor-exit-quit.exp
@@ -49,12 +49,27 @@ set gdbserver_protocol [lindex $res 0]
set gdbserver_gdbport [lindex $res 1]
gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport
-gdb_test_no_output "monitor exit"
-gdb_test_no_output "set confirm off"
+# With non-stop remote targets, the "Remote connection closed" notification is
+# delivered asynchronously and may appear while processing the monitor exit
+# command or shortly after (captured in the quit command later). Handle the
+# early case here.
+set r_conn_closed "Remote connection closed"
+gdb_test_multiple "monitor exit" "monitor exit" {
+ -re -wrap "$r_conn_closed" {
+ pass "$gdb_test_name"
+ }
+ -re -wrap "" {
+ pass "$gdb_test_name"
+ }
+}
set do_cleanup 1
-gdb_test_multiple "quit" "" {
+gdb_test_multiple "with confirm off -- quit" "" {
+ -re -wrap "$r_conn_closed" {
+ # Async "Remote connection closed" from monitor exit, delivered late.
+ exp_continue
+ }
-re -wrap "" {
fail "$gdb_test_name (prompt)"
# Let default_gdb_exit do the cleanup.
--
2.43.0
Intel Deutschland GmbH
Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 89 991 430, www.intel.de
Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell
Chairperson of the Supervisory Board: Nicole Lau
Registered Seat: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH v4 09/11] gdb, testsuite: update attach-deleted-exec.exp to handle async messages
2026-07-14 9:21 [PATCH v4 00/11] Add AlwaysNonStop remote protocol extension Mohamed Bouhaouel
` (7 preceding siblings ...)
2026-07-14 9:21 ` [PATCH v4 08/11] gdb, testsuite: handle async close in monitor-exit-quit.exp Mohamed Bouhaouel
@ 2026-07-14 9:21 ` Mohamed Bouhaouel
2026-07-14 9:21 ` [PATCH v4 10/11] gdb, testsuite: add kfails for step-over-process-exit.exp Mohamed Bouhaouel
2026-07-14 9:21 ` [PATCH v4 11/11] gdb, gdbserver: add AlwaysNonStop remote protocol extension Mohamed Bouhaouel
10 siblings, 0 replies; 13+ messages in thread
From: Mohamed Bouhaouel @ 2026-07-14 9:21 UTC (permalink / raw)
To: gdb-patches; +Cc: markus.t.metzger, stephan.rohr, eliz, aburgess, pedro
From: "Bouhaouel, Mohamed" <mohamed.bouhaouel@intel.com>
With non-stop targets, async thread notifications can appear between
output lines during attach. Also, multiple "Reading symbols from"
messages are printed, so we need to specifically match the /proc/
path to capture the correct filename.
Output example on a non-stop remote target:
(gdb) attach 33604
Attaching to process 33604
[New Thread 33604.33604 (id 1)]
Reading symbols from /proc/33604/exe...
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...
Reading symbols from /usr/lib/debug/.build-id/8e/9fd827446c24067541ac5390e6f527fb5947bb.debug...
Reading symbols from /lib64/ld-linux-x86-64.so.2...
Reading symbols from /usr/lib/debug/.build-id/da/07864eb4c1b06504b8688d25d7e84759fe708d.debug...
[Switching to Thread 33604.33604]
0x00007c9166eeca7a in __GI___clock_nanosleep ...
Reproducible when running gdb.base/attach-deleted-exec.exp, on
native-extended-gdbserver with target-non-stop enabled.
export GDBFLAGS="-iex \"maint set target-non-stop on\""
make check TESTS="gdb.base/attach-deleted-exec.exp" \
RUNTESTFLAGS="--target_board=native-extended-gdbserver GDBFLAGS='$GDBFLAGS'"
---
.../gdb.base/attach-deleted-exec.exp | 59 +++++++++++--------
1 file changed, 34 insertions(+), 25 deletions(-)
diff --git a/gdb/testsuite/gdb.base/attach-deleted-exec.exp b/gdb/testsuite/gdb.base/attach-deleted-exec.exp
index 5d3f43eff00..69233ddaffd 100644
--- a/gdb/testsuite/gdb.base/attach-deleted-exec.exp
+++ b/gdb/testsuite/gdb.base/attach-deleted-exec.exp
@@ -45,26 +45,29 @@ clean_restart
# Attach. GDB should spot that the executable is gone and fallback to
# use /proc/PID/exe.
-set test "attach to process with deleted executable"
-set re \
- [multi_line \
- "Attaching to process $decimal" \
- "Reading symbols from (\[^\r\n\]+)[string_to_regexp ...]" \
- ".*"]
-set filename ""
-gdb_test_multiple "attach $testpid" $test {
- -re -wrap $re {
- set filename $expect_out(1,string)
- pass $gdb_test_name
+set attached_pid "no pid"
+gdb_test_multiple "attach $testpid" "attach to process with deleted executable" {
+ -re "Attaching to process $decimal\r\n" {
+ exp_continue
+ }
+ -re "\\\[New Thread \[^\r\n\]+\\\]\r\n" {
+ # Non-stop targets may emit async thread notifications.
+ exp_continue
+ }
+ -re "Reading symbols from /proc/($decimal)/exe[string_to_regexp ...]" {
+ set attached_pid $expect_out(1,string)
+ exp_continue
+ }
+ -re "Reading symbols from (\[^\r\n\]+[string_to_regexp /.nfs]\[^\r\n\]*)[string_to_regexp ...]" {
+ unsupported $gdb_test_name
+ return
+ }
+ -re "Reading symbols from \[^\r\n\]+[string_to_regexp ...]\r\n" {
+ exp_continue
+ }
+ -re -wrap "" {
+ gdb_assert { $attached_pid == $testpid } $gdb_test_name
}
-}
-
-set test "filename /proc/PID/exe"
-set re_nfs \[^\r\n\]+[string_to_regexp /.nfs]\[^\r\n\]+
-if { [regexp $re_nfs $filename] } {
- unsupported $test
-} else {
- gdb_assert { [string equal $filename /proc/${testpid}/exe] } $test
}
# Restart GDB.
@@ -97,12 +100,18 @@ if { [target_info gdb_protocol] == "extended-remote" } {
set filename_re "\[^\r\n\]+/${testfile} \\(deleted\\)"
}
-gdb_test "attach $testpid" \
- [multi_line \
- "Attaching to process $decimal" \
- "warning: No executable has been specified, and target executable $filename_re could not be found\\. Try using the \"file\" command\\." \
- ".*"] \
- "attach to inferior"
+gdb_test_multiple "attach $testpid" "attach to inferior" {
+ -re "Attaching to process $decimal\r\n" {
+ exp_continue
+ }
+ -re "\\\[New Thread \[^\r\n\]+\\\]\r\n" {
+ # Non-stop targets may emit async thread notifications.
+ exp_continue
+ }
+ -re -wrap "warning: No executable has been specified, and target executable $filename_re could not be found\\. Try using the \"file\" command\\..*" {
+ pass $gdb_test_name
+ }
+}
# Check GDB hasn't managed to load an executable.
gdb_test "info inferior" \
--
2.43.0
Intel Deutschland GmbH
Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 89 991 430, www.intel.de
Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell
Chairperson of the Supervisory Board: Nicole Lau
Registered Seat: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH v4 10/11] gdb, testsuite: add kfails for step-over-process-exit.exp
2026-07-14 9:21 [PATCH v4 00/11] Add AlwaysNonStop remote protocol extension Mohamed Bouhaouel
` (8 preceding siblings ...)
2026-07-14 9:21 ` [PATCH v4 09/11] gdb, testsuite: update attach-deleted-exec.exp to handle async messages Mohamed Bouhaouel
@ 2026-07-14 9:21 ` Mohamed Bouhaouel
2026-07-14 9:21 ` [PATCH v4 11/11] gdb, gdbserver: add AlwaysNonStop remote protocol extension Mohamed Bouhaouel
10 siblings, 0 replies; 13+ messages in thread
From: Mohamed Bouhaouel @ 2026-07-14 9:21 UTC (permalink / raw)
To: gdb-patches; +Cc: markus.t.metzger, stephan.rohr, eliz, aburgess, pedro
From: "Bouhaouel, Mohamed" <mohamed.bouhaouel@intel.com>
When running 'gdb.threads/step-over-process-exit.exp' against a
remote target in non-stop mode, GDB fails with a "Remote
communication error" and does not display the expected
"[Inferior ... exited normally]" message. The test passes in
all-stop mode but fails when target-non-stop is enabled.
Mark the affected assertions as kfail referencing the bug report
gdb/34142 until the underlying issue is resolved.
Reproducible when running gdb.threads/step-over-process-exit.exp, on
native-extended-gdbserver with target-non-stop enabled.
export GDBFLAGS="-iex \"maint set target-non-stop on\""
make check TESTS="gdb.threads/step-over-process-exit.exp" \
RUNTESTFLAGS="--target_board=native-extended-gdbserver GDBFLAGS='$GDBFLAGS'"
---
gdb/testsuite/gdb.threads/step-over-process-exit.exp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/gdb/testsuite/gdb.threads/step-over-process-exit.exp b/gdb/testsuite/gdb.threads/step-over-process-exit.exp
index 6c98ebe3956..72d270c907a 100644
--- a/gdb/testsuite/gdb.threads/step-over-process-exit.exp
+++ b/gdb/testsuite/gdb.threads/step-over-process-exit.exp
@@ -35,6 +35,11 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthread}
# thread, or "other" for the non-main thread.
proc test {which} {
+ if {$which == "other"} {
+ # The failure from the first iteration prevents
+ # the second iteration to run.
+ setup_kfail "gdb/34142" "*-*-*"
+ }
if {![runto_main]} {
return -1
}
@@ -48,6 +53,7 @@ proc test {which} {
set target_non_stop [is_target_non_stop]
+ setup_kfail "gdb/34142" "*-*-*"
gdb_test_multiple "next" "" {
-re -wrap "$::inferior_exited_re normally\\\]" {
pass $gdb_test_name
--
2.43.0
Intel Deutschland GmbH
Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 89 991 430, www.intel.de
Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell
Chairperson of the Supervisory Board: Nicole Lau
Registered Seat: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH v4 11/11] gdb, gdbserver: add AlwaysNonStop remote protocol extension
2026-07-14 9:21 [PATCH v4 00/11] Add AlwaysNonStop remote protocol extension Mohamed Bouhaouel
` (9 preceding siblings ...)
2026-07-14 9:21 ` [PATCH v4 10/11] gdb, testsuite: add kfails for step-over-process-exit.exp Mohamed Bouhaouel
@ 2026-07-14 9:21 ` Mohamed Bouhaouel
2026-07-14 12:07 ` Eli Zaretskii
10 siblings, 1 reply; 13+ messages in thread
From: Mohamed Bouhaouel @ 2026-07-14 9:21 UTC (permalink / raw)
To: gdb-patches; +Cc: markus.t.metzger, stephan.rohr, eliz, aburgess, pedro
From: "Bouhaouel, Mohamed" <mohamed.bouhaouel@intel.com>
Add a new RSP extension allowing remote stubs to declare that a target
prefers to operate in non-stop mode.
When a stub advertises "AlwaysNonStop+" in its qSupported response:
* The stub automatically initializes to non-stop mode.
* GDB will operate the stub in non-stop mode (with default settings).
* The stub may reject QNonStop:0 requests with descriptive error
messages.
* GDB allows connection even if 'maint set target-non-stop off' is set,
but lets the stub decide whether to accept mode switches.
Additionally, gdbserver now accepts --enable-packet=PACKET to enable
specific remote protocol packets or extensions at startup. Currently
this supports the 'AlwaysNonStop' extension.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
---
gdb/NEWS | 13 +++
gdb/doc/gdb.texinfo | 46 ++++++++++-
gdb/remote.c | 21 +++++
.../gdb.server/enable-always-non-stop.exp | 56 +++++++++++++
gdbserver/server.cc | 79 +++++++++++++++++--
gdbserver/server.h | 2 +
gdbserver/target.cc | 6 ++
gdbserver/target.h | 6 ++
8 files changed, 223 insertions(+), 6 deletions(-)
create mode 100644 gdb/testsuite/gdb.server/enable-always-non-stop.exp
diff --git a/gdb/NEWS b/gdb/NEWS
index ec9b5a33787..4f75a55af5d 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -22,6 +22,10 @@
this flag is used gdbserver will not escape special shell characters
within the inferior arguments.
+* gdbserver now accepts --enable-packet=PACKET to enable specific remote
+ protocol packets or extensions at startup. Currently this supports
+ 'AlwaysNonStop' to force the target to always operate in non-stop mode.
+
* The add-inferior, clone-inferior, and MI -add-inferior commands will
now give a warning, and create the new inferior without a
connection, when the current inferior's connection, at the time the
@@ -116,6 +120,15 @@
intent to remove it in a future release.
The s390 64-bit target (s390x-*) remains supported.
+* New remote protocol extension 'AlwaysNonStop' allows gdbserver to
+ indicate that the target prefers to operate in non-stop mode. When a
+ remote stub advertises 'AlwaysNonStop+' in its qSupported reply, GDB
+ will operate the stub in non-stop mode (when 'maint set target-non-stop'
+ is 'auto', the default). If the user explicitly sets 'maint set
+ target-non-stop off', GDB will allow the connection but the stub may
+ reject attempts to switch to all-stop mode with a descriptive error
+ message.
+
* Configure changes
** --with-babeltrace has been removed. The babeltrace library was
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index a698b2b8451..3019cb915f2 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -42922,7 +42922,9 @@ does not indicate support.
@item maint set target-non-stop off
@value{GDBN} does not control the target in non-stop mode even if the
-target supports it.
+target supports it. Note: targets that prefer non-stop mode (via
+@samp{AlwaysNonStop+}) may reject attempts to switch to all-stop mode
+with a descriptive error message.
@end table
Here is how @code{set non-stop} and @code{maint set target-non-stop}
@@ -45094,6 +45096,12 @@ Reply:
@table @samp
@item OK
The request succeeded.
+
+@item @samp{E.@var{message}}
+The request failed. This may occur if the stub prefers non-stop mode
+and advertised @samp{AlwaysNonStop+} support, and @value{GDBN} attempted to
+switch to all-stop mode with @samp{QNonStop:0}. The stub returns a
+textual error message describing why the mode switch was rejected.
@end table
This packet is not probed by default; the remote stub must request it,
@@ -45511,6 +45519,22 @@ multiple-watchpoint-addresses-packet} command (@pxref{Remote
Configuration, set remote multiple-watchpoint-addresses-packet}).
@end table
+@item AlwaysNonStop
+This feature indicates that @value{GDBN} supports remote stubs that
+prefer non-stop mode operation. If the stub advertises
+@samp{AlwaysNonStop+}, it will run in non-stop mode, similar to
+the setting @code{maint set target-non-stop on}. If @value{GDBN}
+attempts to switch the target to all-stop mode, the stub may reject
+the request with a descriptive error message.
+
+Note: @samp{AlwaysNonStop+} requires @samp{QNonStop+} support.
+If a stub advertises @samp{AlwaysNonStop+} without @samp{QNonStop+},
+the @samp{AlwaysNonStop+} extension will be silently ignored by @value{GDBN}.
+
+Use of this feature is controlled by the @code{set remote
+always-non-stop-feature-packet} command (@pxref{Remote
+Configuration, set remote always-non-stop-feature-packet}).
+
Stubs should ignore any unknown values for
@var{gdbfeature}. Any @value{GDBN} which sends a @samp{qSupported}
packet supports receiving packets of unlimited length (earlier
@@ -45907,6 +45931,13 @@ packet (@pxref{qXfer fdpic loadmap read}).
The remote stub understands the @samp{QNonStop} packet
(@pxref{QNonStop}).
+@item AlwaysNonStop
+The remote stub prefers non-stop mode operation, may reject
+@samp{QNonStop:0} requests with a descriptive error message, and
+automatically initializes to non-stop mode. This feature must be
+advertised together with @samp{QNonStop+}; if advertised without it,
+the feature will be silently ignored by @value{GDBN}. @xref{QNonStop}.
+
@item QCatchSyscalls
The remote stub understands the @samp{QCatchSyscalls} packet
(@pxref{QCatchSyscalls}).
@@ -52204,6 +52235,19 @@ option special shell characters will not be escaped. When
@command{gdbserver} starts a new shell in order to invoke the
inferior, this new shell will expand any special shell characters.
+@item --enable-packet=@var{packet}@r{[},@var{packet}@dots{}@r{]}
+Enable specific remote protocol packets or extensions at startup.
+The @var{packet} argument can be one of the following:
+
+@table @code
+@item AlwaysNonStop
+Force the target to always operate in non-stop mode. When this
+extension is enabled, @command{gdbserver} will reject any attempts
+by @value{GDBN} to switch to all-stop mode with a descriptive error
+message. This is useful for targets that require non-stop mode
+for correct operation.
+@end table
+
@c --disable-packet is not documented for users.
@c --disable-randomization and --no-disable-randomization are superseded by
diff --git a/gdb/remote.c b/gdb/remote.c
index b1bc1283b9a..fc5fb6cd160 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -323,6 +323,9 @@ enum {
/* Support for the QNonStop packet. */
PACKET_QNonStop,
+ /* Support for AlwaysNonStop extension. */
+ PACKET_AlwaysNonStop_feature,
+
/* Support for the QThreadEvents packet. */
PACKET_QThreadEvents,
@@ -1442,6 +1445,8 @@ class remote_target : public process_stratum_target
void check_binary_download (CORE_ADDR addr);
+ bool always_non_stop_p () override;
+
target_xfer_status remote_write_bytes_aux (const char *header,
CORE_ADDR memaddr,
const gdb_byte *myaddr,
@@ -6133,6 +6138,8 @@ static const struct protocol_feature remote_protocol_features[] = {
{ "multiprocess", PACKET_DISABLE, remote_supported_packet,
PACKET_multiprocess_feature },
{ "QNonStop", PACKET_DISABLE, remote_supported_packet, PACKET_QNonStop },
+ { "AlwaysNonStop", PACKET_DISABLE, remote_supported_packet,
+ PACKET_AlwaysNonStop_feature },
{ "qXfer:siginfo:read", PACKET_DISABLE, remote_supported_packet,
PACKET_qXfer_siginfo_read },
{ "qXfer:siginfo:write", PACKET_DISABLE, remote_supported_packet,
@@ -9817,6 +9824,18 @@ remote_target::check_binary_download (CORE_ADDR addr)
}
}
+/* Determine whether the remote target operates in non-stop mode.
+ Returns true if the target advertises AlwaysNonStop, and supports
+ QNonStop for asynchronous execution and stop notifications. */
+
+bool
+remote_target::always_non_stop_p ()
+{
+ return ((m_features.packet_support (PACKET_QNonStop) == PACKET_ENABLE)
+ && (m_features.packet_support (PACKET_AlwaysNonStop_feature)
+ == PACKET_ENABLE));
+}
+
/* Helper function to resize the payload in order to try to get a good
alignment. We try to write an amount of data such that the next write will
start on an address aligned on REMOTE_ALIGN_WRITES. */
@@ -17073,6 +17092,8 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
add_packet_config_cmd (PACKET_multi_wp_addr,
"multi-wp-addr", "multiple-watchpoint-addresses", 0);
+ add_packet_config_cmd (PACKET_AlwaysNonStop_feature,
+ "AlwaysNonStop", "always-non-stop-feature", 0);
/* Assert that we've registered "set remote foo-packet" commands
for all packet configs. */
diff --git a/gdb/testsuite/gdb.server/enable-always-non-stop.exp b/gdb/testsuite/gdb.server/enable-always-non-stop.exp
new file mode 100644
index 00000000000..c05f58847bb
--- /dev/null
+++ b/gdb/testsuite/gdb.server/enable-always-non-stop.exp
@@ -0,0 +1,56 @@
+# This testcase is part of GDB, the GNU debugger.
+#
+# Copyright 2026 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 the --enable-packet=AlwaysNonStop gdbserver command line option
+# causes GDB to operate gdbserver with target-non-stop mode enabled.
+
+load_lib gdbserver-support.exp
+
+require allow_gdbserver_tests
+
+standard_testfile server.c
+
+if { [build_executable "failed to prepare" $testfile $srcfile] == -1 } {
+ return
+}
+set target_binfile [gdb_remote_download target $binfile]
+
+save_vars { ::GDBFLAGS } {
+ if { ![is_remote host] && ![is_remote target] } {
+ set ::GDBFLAGS "$::GDBFLAGS -ex \"set sysroot\""
+ }
+ clean_restart $::testfile
+}
+gdb_test "disconnect" ".*"
+
+# Start gdbserver with --enable-packet=AlwaysNonStop
+set res [gdbserver_start "--enable-packet=AlwaysNonStop" $::target_binfile]
+set protocol [lindex $res 0]
+set port [lindex $res 1]
+
+set res [gdb_target_cmd $protocol $port]
+if { ![gdb_assert {$res == 0} "connect"] } {
+ return
+}
+
+# Check that target-non-stop is on
+gdb_test "maint show target-non-stop" \
+ "Whether the target is always in non-stop mode is auto \\(currently on\\)\\." \
+ "verify target-non-stop is on"
+
+# continue to end
+gdb_continue_to_end
diff --git a/gdbserver/server.cc b/gdbserver/server.cc
index 4a727c465f0..614e807271f 100644
--- a/gdbserver/server.cc
+++ b/gdbserver/server.cc
@@ -147,6 +147,9 @@ bool disable_packet_qC;
bool disable_packet_qfThreadInfo;
bool disable_packet_T;
+/* Set if you want to enable optional packets or extensions via CLI. */
+bool enable_always_non_stop;
+
static unsigned char *mem_buf;
/* A sub-class of 'struct notif_event' for stop, holding information
@@ -838,10 +841,19 @@ handle_general_set (char *own_buf)
}
req_str = req ? "non-stop" : "all-stop";
- if (the_target->start_non_stop (req == 1) != 0)
+
+ try
{
- fprintf (stderr, "Setting %s mode failed\n", req_str);
- write_enn (own_buf);
+ if (the_target->start_non_stop (req == 1) != 0)
+ {
+ sprintf (own_buf, "E.Setting %s mode failed.", req_str);
+ return;
+ }
+ }
+ catch (const gdb_exception_error &exception)
+ {
+ /* The target rejected the setting, forward the error message. */
+ sprintf (own_buf, "E.%s", exception.what ());
return;
}
@@ -2812,7 +2824,11 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
strcat (own_buf, ";exec-events+");
if (target_supports_non_stop ())
- strcat (own_buf, ";QNonStop+");
+ {
+ strcat (own_buf, ";QNonStop+");
+ if (target_always_non_stop ())
+ strcat (own_buf, ";AlwaysNonStop+");
+ }
if (target_supports_disable_randomization ())
strcat (own_buf, ";QDisableRandomization+");
@@ -2876,6 +2892,19 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
if (cs.single_inferior_argument)
strcat (own_buf, ";single-inf-arg+");
+ /* If the target requires non-stop mode, initialize it now rather
+ than waiting for GDB to request it via QNonStop:1. */
+ if (target_supports_non_stop () && target_always_non_stop ())
+ {
+ if (the_target->start_non_stop (true) != 0)
+ error ("Cannot initialize target: requires non-stop mode but "
+ "non-stop mode initialization failed.");
+
+ non_stop = true;
+ remote_debug_printf ("Target requires non-stop mode: "
+ "enabled at startup.\n");
+ }
+
/* Reinitialize components as needed for the new connection. */
hostio_handle_new_gdb_connection ();
target_handle_new_gdb_connection ();
@@ -3931,6 +3960,10 @@ gdbserver_usage (FILE *stream)
" Options:\n"
" vCont, vConts, T, Tthread, qC, qfThreadInfo and\n"
" threads (disable all threading packets).\n"
+ " --enable-packet=OPT1[,OPT2,...]\n"
+ " Enable support for RSP packets or extensions.\n"
+ " Options:\n"
+ " AlwaysNonStop.\n"
"\n"
"For more information, consult the GDB manual (available as on-line \n"
"info or a printed manual).\n");
@@ -3951,6 +3984,13 @@ gdbserver_show_disableable (FILE *stream)
" T \tAll 'T' packets\n");
}
+static void
+gdbserver_show_enableable (FILE *stream)
+{
+ fprintf (stream, "Enableable packets:\n"
+ " AlwaysNonStop\tForce AlwaysNonStop extension\n");
+}
+
/* Start up the event loop. This is the entry point to the event
loop. */
@@ -4186,7 +4226,7 @@ captured_main (int argc, char *argv[])
enum opts { OPT_VERSION = 1, OPT_HELP, OPT_ATTACH, OPT_MULTI, OPT_WRAPPER,
OPT_DEBUG, OPT_DEBUG_FILE, OPT_DEBUG_FORMAT, OPT_DISABLE_PACKET,
- OPT_DISABLE_RANDOMIZATION, OPT_NO_DISABLE_RANDOMIZATION,
+ OPT_ENABLE_PACKET, OPT_DISABLE_RANDOMIZATION, OPT_NO_DISABLE_RANDOMIZATION,
OPT_STARTUP_WITH_SHELL, OPT_NO_STARTUP_WITH_SHELL, OPT_ONCE,
OPT_SELFTEST, OPT_NO_ESCAPE
};
@@ -4204,6 +4244,9 @@ captured_main (int argc, char *argv[])
/* --disable-packet is optional_argument only so that we can print a
better help list when the argument is missing. */
{"disable-packet", optional_argument, nullptr, OPT_DISABLE_PACKET},
+ /* --enable-packet is optional_argument only so that we can print a
+ better help list when the argument is missing. */
+ {"enable-packet", optional_argument, nullptr, OPT_ENABLE_PACKET},
{"disable-randomization", no_argument, nullptr,
OPT_DISABLE_RANDOMIZATION},
{"no-disable-randomization", no_argument, nullptr,
@@ -4411,6 +4454,32 @@ captured_main (int argc, char *argv[])
}
break;
+ case OPT_ENABLE_PACKET:
+ {
+ char *packets = optarg;
+ if (packets == nullptr)
+ {
+ gdbserver_show_enableable (stdout);
+ exit (1);
+ }
+ char *saveptr;
+ for (char *tok = strtok_r (packets, ",", &saveptr);
+ tok != nullptr;
+ tok = strtok_r (nullptr, ",", &saveptr))
+ {
+ if (streq ("AlwaysNonStop", tok))
+ enable_always_non_stop = true;
+ else
+ {
+ fprintf (stderr, "Don't know how to enable \"%s\".\n\n",
+ tok);
+ gdbserver_show_enableable (stderr);
+ exit (1);
+ }
+ }
+ }
+ break;
+
case OPT_DISABLE_RANDOMIZATION:
cs.disable_randomization = 1;
break;
diff --git a/gdbserver/server.h b/gdbserver/server.h
index bbba3650de7..4238882dfc7 100644
--- a/gdbserver/server.h
+++ b/gdbserver/server.h
@@ -74,6 +74,8 @@ extern bool disable_packet_qC;
extern bool disable_packet_qfThreadInfo;
extern bool disable_packet_T;
+extern bool enable_always_non_stop;
+
extern bool run_once;
extern bool non_stop;
diff --git a/gdbserver/target.cc b/gdbserver/target.cc
index 43ef421df74..6ce584c8aba 100644
--- a/gdbserver/target.cc
+++ b/gdbserver/target.cc
@@ -498,6 +498,12 @@ process_stratum_target::supports_non_stop ()
return false;
}
+bool
+process_stratum_target::always_non_stop ()
+{
+ return enable_always_non_stop;
+}
+
bool
process_stratum_target::async (bool enable)
{
diff --git a/gdbserver/target.h b/gdbserver/target.h
index 82eab9d1243..cdd1e26f2d6 100644
--- a/gdbserver/target.h
+++ b/gdbserver/target.h
@@ -260,6 +260,9 @@ class process_stratum_target
/* Return true if non-stop mode is supported. */
virtual bool supports_non_stop ();
+ /* Return true if target must run in non-stop mode. */
+ virtual bool always_non_stop ();
+
/* Enables async target events. Returns the previous enable
state. */
virtual bool async (bool enable);
@@ -583,6 +586,9 @@ int kill_inferior (process_info *proc);
#define target_supports_non_stop() \
the_target->supports_non_stop ()
+#define target_always_non_stop() \
+ the_target->always_non_stop ()
+
#define target_async(enable) \
the_target->async (enable)
--
2.43.0
Intel Deutschland GmbH
Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany
Tel: +49 89 991 430, www.intel.de
Managing Directors: Harry Demas, Jeffrey Schneiderman, Yin Chong Sorrell
Chairperson of the Supervisory Board: Nicole Lau
Registered Seat: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH v4 11/11] gdb, gdbserver: add AlwaysNonStop remote protocol extension
2026-07-14 9:21 ` [PATCH v4 11/11] gdb, gdbserver: add AlwaysNonStop remote protocol extension Mohamed Bouhaouel
@ 2026-07-14 12:07 ` Eli Zaretskii
0 siblings, 0 replies; 13+ messages in thread
From: Eli Zaretskii @ 2026-07-14 12:07 UTC (permalink / raw)
To: Mohamed Bouhaouel
Cc: gdb-patches, markus.t.metzger, stephan.rohr, aburgess, pedro
> From: Mohamed Bouhaouel <mohamed.bouhaouel@intel.com>
> Cc: markus.t.metzger@intel.com,
> stephan.rohr@intel.com,
> eliz@gnu.org,
> aburgess@redhat.com,
> pedro@palves.net
> Date: Tue, 14 Jul 2026 11:21:28 +0200
>
> From: "Bouhaouel, Mohamed" <mohamed.bouhaouel@intel.com>
>
> Add a new RSP extension allowing remote stubs to declare that a target
> prefers to operate in non-stop mode.
>
> When a stub advertises "AlwaysNonStop+" in its qSupported response:
>
> * The stub automatically initializes to non-stop mode.
> * GDB will operate the stub in non-stop mode (with default settings).
> * The stub may reject QNonStop:0 requests with descriptive error
> messages.
> * GDB allows connection even if 'maint set target-non-stop off' is set,
> but lets the stub decide whether to accept mode switches.
>
> Additionally, gdbserver now accepts --enable-packet=PACKET to enable
> specific remote protocol packets or extensions at startup. Currently
> this supports the 'AlwaysNonStop' extension.
>
> Reviewed-By: Eli Zaretskii <eliz@gnu.org>
> ---
> gdb/NEWS | 13 +++
> gdb/doc/gdb.texinfo | 46 ++++++++++-
> gdb/remote.c | 21 +++++
> .../gdb.server/enable-always-non-stop.exp | 56 +++++++++++++
> gdbserver/server.cc | 79 +++++++++++++++++--
> gdbserver/server.h | 2 +
> gdbserver/target.cc | 6 ++
> gdbserver/target.h | 6 ++
> 8 files changed, 223 insertions(+), 6 deletions(-)
> create mode 100644 gdb/testsuite/gdb.server/enable-always-non-stop.exp
Thanks, the documentation parts are okay.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
^ permalink raw reply [flat|nested] 13+ messages in thread