From e42f681304954272e72d2e2f9d61d68bec29953f Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Wed, 3 Dec 2025 15:15:42 +0000 Subject: [PATCH] GDB RP: support `D` detach command In our case it behaves similarly to the `kill` command, but finishes execution before stopping the debugger server. --- Sources/GDBRemoteProtocol/GDBHostCommand.swift | 3 +++ Sources/WasmKit/Execution/Debugger.swift | 3 ++- Sources/WasmKitGDBHandler/WasmKitGDBHandler.swift | 8 ++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Sources/GDBRemoteProtocol/GDBHostCommand.swift b/Sources/GDBRemoteProtocol/GDBHostCommand.swift index 4b28f6ee..d46d0524 100644 --- a/Sources/GDBRemoteProtocol/GDBHostCommand.swift +++ b/Sources/GDBRemoteProtocol/GDBHostCommand.swift @@ -49,6 +49,7 @@ package struct GDBHostCommand: Equatable { case removeSoftwareBreakpoint case wasmLocal case memoryRegionInfo + case detach case generalRegisters @@ -103,6 +104,8 @@ package struct GDBHostCommand: Equatable { self = .wasmLocal case "qMemoryRegionInfo": self = .memoryRegionInfo + case "D": + self = .detach default: return nil diff --git a/Sources/WasmKit/Execution/Debugger.swift b/Sources/WasmKit/Execution/Debugger.swift index c91f2ca8..3a14896b 100644 --- a/Sources/WasmKit/Execution/Debugger.swift +++ b/Sources/WasmKit/Execution/Debugger.swift @@ -44,7 +44,8 @@ /// Threading model of the Wasm engine configuration, cached for a potentially hot path. private let threadingModel: EngineConfiguration.ThreadingModel - private(set) var breakpoints = [Int: CodeSlot]() + /// Mapping from a Wasm address of a breakpoint to a corresponding iseq code slot. + package private(set) var breakpoints = [Int: UInt64]() package private(set) var state: State diff --git a/Sources/WasmKitGDBHandler/WasmKitGDBHandler.swift b/Sources/WasmKitGDBHandler/WasmKitGDBHandler.swift index 6af172a3..a50f2500 100644 --- a/Sources/WasmKitGDBHandler/WasmKitGDBHandler.swift +++ b/Sources/WasmKitGDBHandler/WasmKitGDBHandler.swift @@ -281,6 +281,14 @@ case .kill: throw Error.killRequestReceived + case .detach: + for address in self.debugger.breakpoints.keys { + try self.debugger.disableBreakpoint(address: address) + } + + try self.debugger.run() + throw Error.killRequestReceived + case .insertSoftwareBreakpoint: try self.debugger.enableBreakpoint( address: Int(