Skip to content

Commit ad68248

Browse files
committed
Fix QStartNoAckMode handling
1 parent 05cd857 commit ad68248

File tree

5 files changed

+53
-28
lines changed

5 files changed

+53
-28
lines changed

Sources/GDBRemoteProtocol/GDBHostCommandDecoder.swift

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ extension ByteBuffer {
1313

1414
package struct GDBHostCommandDecoder: ByteToMessageDecoder {
1515
enum Error: Swift.Error {
16+
case expectedAck
1617
case expectedCommandStart
1718
case unknownCommandKind(String)
1819
case expectedChecksum
@@ -35,25 +36,41 @@ package struct GDBHostCommandDecoder: ByteToMessageDecoder {
3536
UInt8(self.accummulatedSum % 256)
3637
}
3738

39+
private var isNoAckModeRequested = false
40+
private var isNoAckModeActive = false
41+
3842
mutating package func decode(buffer: inout ByteBuffer) throws -> GDBPacket<GDBHostCommand>? {
39-
guard let firstStartDelimiter = self.accumulatedDelimiter ?? buffer.readInteger(as: UInt8.self) else {
43+
guard var startDelimiter = self.accumulatedDelimiter ?? buffer.readInteger(as: UInt8.self) else {
4044
// Not enough data to parse.
4145
return nil
4246
}
43-
guard let secondStartDelimiter = buffer.readInteger(as: UInt8.self) else {
44-
// Preserve what we already read.
45-
self.accumulatedDelimiter = firstStartDelimiter
4647

47-
// Not enough data to parse.
48-
return nil
48+
if !isNoAckModeActive {
49+
let firstStartDelimiter = startDelimiter
50+
51+
guard firstStartDelimiter == UInt8(ascii: "+") else {
52+
logger.error("unexpected ack character: \(Character(UnicodeScalar(startDelimiter)))")
53+
throw Error.expectedAck
54+
}
55+
56+
if isNoAckModeRequested {
57+
self.isNoAckModeActive = true
58+
}
59+
60+
guard let secondStartDelimiter = buffer.readInteger(as: UInt8.self) else {
61+
// Preserve what we already read.
62+
self.accumulatedDelimiter = firstStartDelimiter
63+
64+
// Not enough data to parse.
65+
return nil
66+
}
67+
68+
startDelimiter = secondStartDelimiter
4969
}
5070

5171
// Command start delimiters.
52-
guard
53-
firstStartDelimiter == UInt8(ascii: "+")
54-
&& secondStartDelimiter == UInt8(ascii: "$")
55-
else {
56-
logger.error("unexpected delimiter: \(Character(UnicodeScalar(firstStartDelimiter)))\(Character(UnicodeScalar(secondStartDelimiter)))")
72+
guard startDelimiter == UInt8(ascii: "$") else {
73+
logger.error("unexpected delimiter: \(Character(UnicodeScalar(startDelimiter)))")
5774
throw Error.expectedCommandStart
5875
}
5976

@@ -106,6 +123,10 @@ package struct GDBHostCommandDecoder: ByteToMessageDecoder {
106123
throw Error.checksumIncorrect
107124
}
108125

126+
if commandKind == .startNoAckMode {
127+
self.isNoAckModeRequested = true
128+
}
129+
109130
return .init(
110131
payload: .init(
111132
kind: commandKind,

Sources/GDBRemoteProtocol/GDBPacket.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package struct GDBPacket<Payload: Sendable>: Sendable {
22
package let payload: Payload
3-
43
package let checksum: UInt8
54

65
package init(payload: Payload, checksum: UInt8) {

Sources/GDBRemoteProtocol/GDBTargetResponse.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ package struct GDBTargetResponse {
1818
}
1919

2020
package let kind: Kind
21-
package let isNoAckModeActive: Bool
21+
package let isNoAckModeActivated: Bool
2222

23-
package init(kind: Kind, isNoAckModeActive: Bool) {
23+
package init(kind: Kind, isNoAckModeActivated: Bool) {
2424
self.kind = kind
25-
self.isNoAckModeActive = isNoAckModeActive
25+
self.isNoAckModeActivated = isNoAckModeActivated
2626
}
2727
}

Sources/GDBRemoteProtocol/GDBTargetResponseEncoder.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,17 @@ extension String {
77
}
88
}
99

10-
package struct GDBTargetResponseEncoder: MessageToByteEncoder {
10+
package class GDBTargetResponseEncoder: MessageToByteEncoder {
11+
private var isNoAckModeActive = false
12+
1113
package init() {}
1214
package func encode(data: GDBTargetResponse, out: inout ByteBuffer) throws {
13-
if !data.isNoAckModeActive {
15+
if !isNoAckModeActive {
1416
out.writeInteger(UInt8(ascii: "+"))
1517
}
18+
if data.isNoAckModeActivated {
19+
self.isNoAckModeActive = true
20+
}
1621
out.writeInteger(UInt8(ascii: "$"))
1722

1823
switch data.kind {

Sources/WasmKitGDBHandler/WasmKitDebugger.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import GDBRemoteProtocol
22
import Logging
3+
import Synchronization
34
import SystemPackage
45
import WasmKit
56

67
package actor WasmKitDebugger {
7-
/// Whether `QStartNoAckMode` command was previously sent.
8-
private var isNoAckModeActive = false
9-
108
private let module: Module
119
private let logger: Logger
1210

@@ -19,9 +17,14 @@ package actor WasmKitDebugger {
1917
let responseKind: GDBTargetResponse.Kind
2018
logger.trace("handling GDB host command", metadata: ["GDBHostCommand": .string(command.kind.rawValue)])
2119

20+
var isNoAckModeActivated = false
2221
responseKind =
2322
switch command.kind {
24-
case .startNoAckMode, .isThreadSuffixSupported, .listThreadsInStopReply:
23+
case .startNoAckMode:
24+
isNoAckModeActivated = true
25+
fallthrough
26+
27+
case .isThreadSuffixSupported, .listThreadsInStopReply:
2528
.ok
2629

2730
case .hostInfo:
@@ -38,7 +41,7 @@ package actor WasmKitDebugger {
3841
.raw(command.arguments)
3942

4043
case .vContSupportedActions:
41-
.vContSupportedActions([.continue, .step, .stop])
44+
.vContSupportedActions([.continue, .step])
4245

4346
case .isVAttachOrWaitSupported, .enableErrorStrings:
4447
.empty
@@ -64,12 +67,9 @@ package actor WasmKitDebugger {
6467
fatalError()
6568
}
6669

67-
defer {
68-
if command.kind == .startNoAckMode {
69-
self.isNoAckModeActive = true
70-
}
71-
}
72-
return .init(kind: responseKind, isNoAckModeActive: self.isNoAckModeActive)
70+
logger.trace("handler produced a response", metadata: ["GDBTargetResponse": .string("\(responseKind)")])
71+
72+
return .init(kind: responseKind, isNoAckModeActivated: isNoAckModeActivated)
7373
}
7474

7575
}

0 commit comments

Comments
 (0)