From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 4jTBFqTh+WnJnhYAWB0awg (envelope-from ) for ; Tue, 05 May 2026 08:25:08 -0400 Received: by simark.ca (Postfix, from userid 112) id 48BC81E0BA; Tue, 05 May 2026 08:25:08 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.3 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 994F41E067 for ; Tue, 05 May 2026 08:25:06 -0400 (EDT) Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id 852E54BA23EC for ; Tue, 5 May 2026 12:25:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 852E54BA23EC Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) by sourceware.org (Postfix) with ESMTPS id EAC854BA7982 for ; Tue, 5 May 2026 12:24:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org EAC854BA7982 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=palves.net Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org EAC854BA7982 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1777983880; cv=none; b=QFmCYqLsRzEFEVFfSZWLFEO4ErhNhu8Ja3ivRrUeHrtquk/QP/GXIc0X81HUN/zFhGf4yVnmJ+EpnuWRNrT6CUER9PCJ7EPovAjOigHxWo5gLz2r2Htfy0DwML5Mcszwgsz7K/pKtLRm4FaXDJLH7cJ2/19UX9ny7AgAYXVp3H8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1777983880; c=relaxed/simple; bh=NzlLhXptGbCAzzB2hOVYQYYlwqYX6JZ1JgPV14hX6d8=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=xjJ2W1P+zip2vBCBrm8Zhq2u10XDCyjfnaGtxBnj2QECv0uxtoPPJljFkxmenIn4rqwrEzA3nJ+OhjP6o6Wk8hJ5lnRq+m/8z4CstwrVlPoR25U5iRm/l8uZl+07wrWCNdScrbP1LlKCL38tho5j/E+s2pwNW2g4Q4kjRzuTTmE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EAC854BA7982 Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-48d102471a4so18808925e9.2 for ; Tue, 05 May 2026 05:24:39 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777983878; x=1778588678; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=XN98sewxZh++rDqHMcEya19jHE9X7zBcFz99vf+3EEM=; b=QhedKubwNnRGr6MLtEA4fQo8oRnX4AiwdRkuoetLDdJiicrxUUbSS7bpTeD6l95i3u V9GGUJzc8QL/3J3N6WzeNhB9M4gZHnRU5uy6pCz2ThqH82sBCv0MYTaAb9Tu//1iIRXj CCuetm9/JJPdFkqnpQW8HrEyQBYL6aqXmbffx6x1xYy4FCicbp1SFebUYhQYsKEaMe4k sLokQ6rCyCrHXmS2YiQ0ZIxJ5hhb4rODgHAuh22vIooHIjWAeXGcIquq4sM9cDMoVcyo eGSaXvyEm8nye3I61KO+6Kg4S97PaCTotCN/DKJEcpzqWmqHiyuCQ4aHh0HZmCc8H5no pXwQ== X-Gm-Message-State: AOJu0Yzrwh5/DFJuXNwoAxyKKXkJle75qkfl63sivdp8LxOZWGF+1sCh 0/C6kgARHnng42OBOQMpWiARclvefaOzc+3v7fsuZs1HlG9KFBrhFd0zpJOPLg== X-Gm-Gg: AeBDieuClFxfCYc3yyzDi18VJgg3P8wmyMkyrhiygyGDf/UIjgsKRqXL0XWvdA6vdmo IPsTIQTGekIukWk7KUPRIROrXcdpRRGHJ0bfhiMHrzgRnpRxoqPamZQu0nvIYGOobjv9GlQvy3G 5fOsxz4fhZVPu64P75f/0r+NcuotDtGbTmPU+R7t+9hT+JM+oG/rwYZs4OwAT+7tuDoknFKpNb/ p4YQR2n7jkZ47HuZPQaH7u8ydsgfEFFEDjz94XNSQxWWVJlXzkHd4CleWWoMq2BQJXiXZeV7dwP pFiPdwpVUTEiv++EExYB39drNekb28rCOROGZY8cD7D40Dmohxs8lxtGjxXapwELcTj4JSiA2RX K0u/iwdXafUlTb+re6MLCen1UZh6k+vhdVtZEsCbmAX3Z2pd5U2t9nu7MM5NX483T1tDom4oHkF YzzVl2DndlG1f0+9YAUcJxP46Tt4Jfqyq17wNqlIvDmgg= X-Received: by 2002:a05:600c:3e0e:b0:48a:52ce:a4b1 with SMTP id 5b1f17b1804b1-48a98893048mr233431895e9.15.1777983878294; Tue, 05 May 2026 05:24:38 -0700 (PDT) Received: from localhost ([2001:8a0:facb:a800:d362:b803:ffc5:8f78]) by smtp.gmail.com with UTF8SMTPSA id 5b1f17b1804b1-48a8ebb3dc1sm366812005e9.14.2026.05.05.05.24.37 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 05 May 2026 05:24:37 -0700 (PDT) From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH] Windows gdb: all-stop, interrupt with "stopped" instead of SIGTRAP Date: Tue, 5 May 2026 13:24:33 +0100 Message-ID: <20260505122434.1444507-1-pedro@palves.net> X-Mailer: git-send-email 2.53.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org Currently, "interrupt" uses DebugBreakProcess (or equivalent), which injects a new thread in the inferior that executes an int3 instruction (on x86), which raises a SIGTRAP. With the target backend in non-stop mode, its easy to avoid all that and make interrupt in all-stop just suspend a pre-existing thread and report "stopped", like "set non-stop on" does (via target_stop). E.g., before: (gdb) c& Continuing. ... (gdb) info threads Id Target Id Frame * 1 Thread 1180.0x1374 (running) 2 Thread 1180.0xc3c (running) 3 Thread 1180.0x6ec (running) 5 Thread 1180.0x1378 (running) (gdb) ... [New Thread 1180.0xc70] [Thread 1180.0x1378 exited with code 0] [Thread 1180.0xc70 exited with code 0] [New Thread 1180.0xdc0] ... interrupt (gdb) [New Thread 1180.0x1010] Thread 8 received signal SIGTRAP, Trace/breakpoint trap. [Switching to Thread 1180.0x1010] 0x00007ffa57490b71 in ntdll!DbgBreakPoint () from C:\Windows\SYSTEM32\ntdll.dll info threads Id Target Id Frame 1 Thread 1180.0x1374 0x00007ffa5748d6e4 in ntdll!ZwDelayExecution () from C:\Windows\SYSTEM32\ntdll.dll 2 Thread 1180.0xc3c 0x00007ffa57490ad4 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:\Windows\SYSTEM32\ntdll.dll 3 Thread 1180.0x6ec 0x00007ffa5748d6e4 in ntdll!ZwDelayExecution () from C:\Windows\SYSTEM32\ntdll.dll 7 Thread 1180.0xdc0 0x00007ffa5748d6e4 in ntdll!ZwDelayExecution () from C:\Windows\SYSTEM32\ntdll.dll * 8 Thread 1180.0x1010 0x00007ffa57490b71 in ntdll!DbgBreakPoint () from C:\Windows\SYSTEM32\ntdll.dll (gdb) After: (gdb) info threads Id Target Id Frame * 1 Thread 5912.0x394 (running) 2 Thread 5912.0x608 (running) 3 Thread 5912.0x1704 (running) 10 Thread 5912.0x870 (running) (gdb) ... [Thread 5912.0x870 exited with code 0] ... (gdb) interrupt (gdb) Thread 1 stopped. 0x00007ffa5748d6e4 in ntdll!ZwDelayExecution () from C:\Windows\SYSTEM32\ntdll.dll info threads Id Target Id Frame * 1 Thread 5912.0x394 0x00007ffa5748d6e4 in ntdll!ZwDelayExecution () from C:\Windows\SYSTEM32\ntdll.dll 2 Thread 5912.0x608 0x00007ffa57490ad4 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:\Windows\SYSTEM32\ntdll.dll 3 Thread 5912.0x1704 0x00007ffa5748d6e4 in ntdll!ZwDelayExecution () from C:\Windows\SYSTEM32\ntdll.dll 8 Thread 5912.0x1200 0x00007ffa5748d6e4 in ntdll!ZwDelayExecution () from C:\Windows\SYSTEM32\ntdll.dll (gdb) Change-Id: I569fc69392ce9a070a2ebe1003388b7386412b14 commit-id: 8f6b76d2 --- gdb/windows-nat.c | 68 +++++++++++++++++++++++++++++++++++++++-------- gdb/windows-nat.h | 5 +++- 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index a9647e90bb8..b9d32b6c0c4 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -1177,6 +1177,30 @@ void windows_nat_target::interrupt () { DEBUG_EVENTS ("interrupt"); + + if (target_is_non_stop_p ()) + { + /* Since we have finer-grained control and can suspend threads, + we can report a "stopped" event for an existing thread, + instead of force-injecting a new thread that reports SIGTRAP + with DebugBreakProcess. + + Stop one thread, any thread. */ + stop_interrupt (minus_one_ptid, true); + return; + } + + if (!dbg_break_process ()) + warning (_("Could not interrupt program. " + "Press Ctrl-c in the program console.")); +} + +/* Stop the process with DebugBreakProcess or equivalent. Return true + on success, false otherwise. */ + +bool +windows_nat_target::dbg_break_process () +{ #ifdef __x86_64__ if (windows_process->wow64_process) { @@ -1200,23 +1224,25 @@ windows_nat_target::interrupt () if (thread) { CloseHandle (thread); - return; + return true; } } } else #endif if (DebugBreakProcess (windows_process->handle)) - return; - warning (_("Could not interrupt program. " - "Press Ctrl-c in the program console.")); + return true; + + return false; } /* Stop thread TH, for STOPPING_KIND reason. This leaves a GDB_SIGNAL_0 pending in the thread, which is later consumed by - windows_nat_target::wait. */ + windows_nat_target::wait. Return true if TH gets suspended and now + has a new stop event to report; false if TH was already suspended + and has no new stop event. */ -void +bool windows_nat_target::stop_one_thread (windows_thread_info *th, enum stopping_kind stopping_kind) { @@ -1230,6 +1256,7 @@ windows_nat_target::stop_one_thread (windows_thread_info *th, DEBUG_EVENTS ("already suspended %s: suspended=%d, stopping=%d", thr_ptid.to_string ().c_str (), th->suspended, th->stopping); + return false; } #ifdef __CYGWIN__ else if (th->suspended @@ -1249,6 +1276,7 @@ windows_nat_target::stop_one_thread (windows_thread_info *th, th->pending_status.set_stopped (GDB_SIGNAL_0); th->last_event = {}; serial_event_set (m_wait_event); + return true; } #endif else if (th->suspended) @@ -1262,6 +1290,7 @@ windows_nat_target::stop_one_thread (windows_thread_info *th, /* Upgrade stopping. */ if (stopping_kind > th->stopping) th->stopping = stopping_kind; + return false; } else { @@ -1278,7 +1307,7 @@ windows_nat_target::stop_one_thread (windows_thread_info *th, thr_ptid.to_string ().c_str ()); if (stopping_kind > th->stopping) th->stopping = stopping_kind; - return; + return false; } gdb_assert (th->suspended == 1); @@ -1291,21 +1320,38 @@ windows_nat_target::stop_one_thread (windows_thread_info *th, } serial_event_set (m_wait_event); + return true; } } -/* Implementation of target_ops::stop. */ +/* Helper for windows_nat_target::stop and + windows_nat_target::interrupt. Stops PTID. If STOP_ON_FIRST_MATCH + is true, returns immediately as soon as one thread is stopped. */ void -windows_nat_target::stop (ptid_t ptid) +windows_nat_target::stop_interrupt (ptid_t ptid, bool stop_on_first_match) { for (thread_info &thr : all_non_exited_threads (this)) { - if (thr.ptid.matches (ptid)) - stop_one_thread (as_windows_thread_info (&thr), SK_EXTERNAL); + if (!thr.ptid.matches (ptid)) + continue; + + if (stop_one_thread (as_windows_thread_info (&thr), SK_EXTERNAL)) + { + if (stop_on_first_match) + return; + } } } +/* Implementation of target_ops::stop. */ + +void +windows_nat_target::stop (ptid_t ptid) +{ + stop_interrupt (ptid, false); +} + void windows_nat_target::pass_ctrlc () { diff --git a/gdb/windows-nat.h b/gdb/windows-nat.h index 1f7ecb07e4f..8e6e79a8160 100644 --- a/gdb/windows-nat.h +++ b/gdb/windows-nat.h @@ -312,9 +312,12 @@ struct windows_nat_target : public inf_child_target void delete_thread (ptid_t ptid, DWORD exit_code, bool main_thread_p); DWORD fake_create_process (const DEBUG_EVENT ¤t_event); - void stop_one_thread (windows_thread_info *th, + bool stop_one_thread (windows_thread_info *th, enum windows_nat::stopping_kind stopping_kind); + void stop_interrupt (ptid_t ptid, bool stop_on_first_match); + bool dbg_break_process (); + DWORD continue_status_for_event_detaching (const DEBUG_EVENT &event, size_t *reply_later_events_left = nullptr); base-commit: 297fe552edd546e4fe9f47c7a0765a55ce084f0c -- 2.53.0