Skip to content

Commit f6a8dce

Browse files
committed
Improved error detection to catch more cases
1 parent 3ed72de commit f6a8dce

File tree

5 files changed

+38
-18
lines changed

5 files changed

+38
-18
lines changed

arduino-debugger-extension/src/node/arduino-debug-adapter-contribution.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ export class ArduinoDebugAdapterContribution implements DebugAdapterContribution
7070
fqbn: '${fqbn}',
7171
uploadPort: '${port}',
7272
initCommands: [
73-
`-break-insert -t --function ${startFunction}`,
74-
'-interpreter-exec console "monitor reset halt"'
73+
`-break-insert -t --function ${startFunction}`
7574
]
7675
}
7776
if (!res.sketch) {

arduino-debugger-extension/src/node/debug-adapter/arduino-debug-session.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export class ArduinoDebugSession extends GDBDebugSession {
4343

4444
protected async configurationDoneRequest(response: DebugProtocol.ConfigurationDoneResponse): Promise<void> {
4545
try {
46+
await this.gdb.sendCommand('-interpreter-exec console "monitor reset halt"')
4647
await mi.sendExecContinue(this.gdb);
4748
this.sendResponse(response);
4849
} catch (err) {

arduino-debugger-extension/src/node/debug-adapter/arduino-gdb-backend.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ export class ArduinoGDBBackend extends GDBBackend {
4848
return this.sendCommand(command);
4949
}
5050

51-
sendStackInfoFrame(gdb: GDBBackend, threadId: number, frameId: number): Promise<{ frame: MIFrameInfo }> {
51+
sendStackInfoFrame(threadId: number, frameId: number): Promise<{ frame: MIFrameInfo }> {
5252
const command = `-stack-info-frame --thread ${threadId} --frame ${frameId}`;
53-
return gdb.sendCommand(command);
53+
return this.sendCommand(command);
5454
}
5555

5656
sendTargetDetach(): Promise<void> {

arduino-debugger-extension/src/node/debug-adapter/arduino-parser.ts

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,35 @@ const LINE_REGEX = /(.*)(\r?\n)/;
77

88
export class ArduinoParser extends MIParser {
99

10+
protected rejectReady?: (error: Error) => void;
11+
1012
parseFull(proc: ChildProcessWithoutNullStreams): Promise<void> {
1113
return new Promise((resolve, reject) => {
14+
// Detect errors when the child process could not be spawned
1215
proc.on('error', reject);
13-
let ready = false;
14-
proc.on('exit', () => {
15-
if (!ready) {
16-
reject(new Error('The gdb debugger terminated unexpectedly.'));
17-
}
18-
});
19-
16+
// Detect hanging process (does not print command prompt or error)
2017
const timeout = setTimeout(() => {
2118
reject(new Error(`No response from gdb after ${READY_TIMEOUT} ms.`));
2219
}, READY_TIMEOUT);
20+
2321
this.waitReady = () => {
24-
ready = true;
22+
this.rejectReady = undefined;
2523
clearTimeout(timeout);
2624
resolve();
2725
}
26+
this.rejectReady = (error: Error) => {
27+
this.waitReady = undefined;
28+
clearTimeout(timeout);
29+
reject(error);
30+
}
31+
// Detect unexpected termination
32+
proc.on('exit', () => {
33+
if (this.rejectReady) {
34+
this.rejectReady(new Error('The gdb debugger terminated unexpectedly.'));
35+
}
36+
});
2837
this.readInputStream(proc.stdout);
29-
this.readErrorStream(proc.stderr, reject);
38+
this.readErrorStream(proc.stderr);
3039
});
3140
}
3241

@@ -36,25 +45,36 @@ export class ArduinoParser extends MIParser {
3645
buff += chunk.toString();
3746
let regexArray = LINE_REGEX.exec(buff);
3847
while (regexArray) {
39-
this.line = regexArray[1];
48+
const line = regexArray[1];
49+
this.line = line;
4050
this.pos = 0;
4151
this.handleLine();
52+
// Detect error emitted as log message
53+
if (line.startsWith('&"error') && this.rejectReady) {
54+
this.line = line;
55+
this.pos = 0;
56+
this.next();
57+
this.rejectReady(new Error(this.handleCString() || regexArray[1]));
58+
this.rejectReady = undefined;
59+
}
4260
buff = buff.substring(regexArray[1].length + regexArray[2].length);
4361
regexArray = LINE_REGEX.exec(buff);
4462
}
4563
});
4664
}
4765

48-
private readErrorStream(stream: Readable, reject: (reason?: any) => void) {
66+
private readErrorStream(stream: Readable) {
4967
let buff = '';
5068
stream.on('data', chunk => {
5169
buff += chunk.toString();
5270
let regexArray = LINE_REGEX.exec(buff);
5371
while (regexArray) {
5472
const line = regexArray[1];
5573
this.gdb.emit('consoleStreamOutput', line + '\n', 'stderr');
56-
if (line.toLowerCase().startsWith('error')) {
57-
reject(new Error(line));
74+
// Detect error emitted on the stderr stream
75+
if (line.toLowerCase().startsWith('error') && this.rejectReady) {
76+
this.rejectReady(new Error(line));
77+
this.rejectReady = undefined;
5878
}
5979
buff = buff.substring(regexArray[1].length + regexArray[2].length);
6080
regexArray = LINE_REGEX.exec(buff);

arduino-debugger-extension/src/node/debug-adapter/arduino-variable-handler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export class ArduinoVariableHandler {
4848
async getStaticVariables(frameHandle: number): Promise<DebugProtocol.Variable[]> {
4949
throw new Error('Static variables are not supported yet.');
5050
const frame = this.frameHandles.get(frameHandle);
51-
const result = await this.gdb.sendStackInfoFrame(this.gdb, frame.threadId, frame.frameId);
51+
const result = await this.gdb.sendStackInfoFrame(frame.threadId, frame.frameId);
5252
const file = path.normalize(result.frame.file || '');
5353
const symbolInfo: any[] = [] // this.symbolTable.getStaticVariables(file);
5454
const variables: DebugProtocol.Variable[] = [];

0 commit comments

Comments
 (0)