mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-27 05:06:42 +00:00
Improved error detection to catch more cases
This commit is contained in:
parent
3ed72de810
commit
f6a8dceabc
@ -70,8 +70,7 @@ export class ArduinoDebugAdapterContribution implements DebugAdapterContribution
|
||||
fqbn: '${fqbn}',
|
||||
uploadPort: '${port}',
|
||||
initCommands: [
|
||||
`-break-insert -t --function ${startFunction}`,
|
||||
'-interpreter-exec console "monitor reset halt"'
|
||||
`-break-insert -t --function ${startFunction}`
|
||||
]
|
||||
}
|
||||
if (!res.sketch) {
|
||||
|
@ -43,6 +43,7 @@ export class ArduinoDebugSession extends GDBDebugSession {
|
||||
|
||||
protected async configurationDoneRequest(response: DebugProtocol.ConfigurationDoneResponse): Promise<void> {
|
||||
try {
|
||||
await this.gdb.sendCommand('-interpreter-exec console "monitor reset halt"')
|
||||
await mi.sendExecContinue(this.gdb);
|
||||
this.sendResponse(response);
|
||||
} catch (err) {
|
||||
|
@ -48,9 +48,9 @@ export class ArduinoGDBBackend extends GDBBackend {
|
||||
return this.sendCommand(command);
|
||||
}
|
||||
|
||||
sendStackInfoFrame(gdb: GDBBackend, threadId: number, frameId: number): Promise<{ frame: MIFrameInfo }> {
|
||||
sendStackInfoFrame(threadId: number, frameId: number): Promise<{ frame: MIFrameInfo }> {
|
||||
const command = `-stack-info-frame --thread ${threadId} --frame ${frameId}`;
|
||||
return gdb.sendCommand(command);
|
||||
return this.sendCommand(command);
|
||||
}
|
||||
|
||||
sendTargetDetach(): Promise<void> {
|
||||
|
@ -7,26 +7,35 @@ const LINE_REGEX = /(.*)(\r?\n)/;
|
||||
|
||||
export class ArduinoParser extends MIParser {
|
||||
|
||||
protected rejectReady?: (error: Error) => void;
|
||||
|
||||
parseFull(proc: ChildProcessWithoutNullStreams): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Detect errors when the child process could not be spawned
|
||||
proc.on('error', reject);
|
||||
let ready = false;
|
||||
proc.on('exit', () => {
|
||||
if (!ready) {
|
||||
reject(new Error('The gdb debugger terminated unexpectedly.'));
|
||||
}
|
||||
});
|
||||
|
||||
// Detect hanging process (does not print command prompt or error)
|
||||
const timeout = setTimeout(() => {
|
||||
reject(new Error(`No response from gdb after ${READY_TIMEOUT} ms.`));
|
||||
}, READY_TIMEOUT);
|
||||
|
||||
this.waitReady = () => {
|
||||
ready = true;
|
||||
this.rejectReady = undefined;
|
||||
clearTimeout(timeout);
|
||||
resolve();
|
||||
}
|
||||
this.rejectReady = (error: Error) => {
|
||||
this.waitReady = undefined;
|
||||
clearTimeout(timeout);
|
||||
reject(error);
|
||||
}
|
||||
// Detect unexpected termination
|
||||
proc.on('exit', () => {
|
||||
if (this.rejectReady) {
|
||||
this.rejectReady(new Error('The gdb debugger terminated unexpectedly.'));
|
||||
}
|
||||
});
|
||||
this.readInputStream(proc.stdout);
|
||||
this.readErrorStream(proc.stderr, reject);
|
||||
this.readErrorStream(proc.stderr);
|
||||
});
|
||||
}
|
||||
|
||||
@ -36,16 +45,25 @@ export class ArduinoParser extends MIParser {
|
||||
buff += chunk.toString();
|
||||
let regexArray = LINE_REGEX.exec(buff);
|
||||
while (regexArray) {
|
||||
this.line = regexArray[1];
|
||||
const line = regexArray[1];
|
||||
this.line = line;
|
||||
this.pos = 0;
|
||||
this.handleLine();
|
||||
// Detect error emitted as log message
|
||||
if (line.startsWith('&"error') && this.rejectReady) {
|
||||
this.line = line;
|
||||
this.pos = 0;
|
||||
this.next();
|
||||
this.rejectReady(new Error(this.handleCString() || regexArray[1]));
|
||||
this.rejectReady = undefined;
|
||||
}
|
||||
buff = buff.substring(regexArray[1].length + regexArray[2].length);
|
||||
regexArray = LINE_REGEX.exec(buff);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private readErrorStream(stream: Readable, reject: (reason?: any) => void) {
|
||||
private readErrorStream(stream: Readable) {
|
||||
let buff = '';
|
||||
stream.on('data', chunk => {
|
||||
buff += chunk.toString();
|
||||
@ -53,8 +71,10 @@ export class ArduinoParser extends MIParser {
|
||||
while (regexArray) {
|
||||
const line = regexArray[1];
|
||||
this.gdb.emit('consoleStreamOutput', line + '\n', 'stderr');
|
||||
if (line.toLowerCase().startsWith('error')) {
|
||||
reject(new Error(line));
|
||||
// Detect error emitted on the stderr stream
|
||||
if (line.toLowerCase().startsWith('error') && this.rejectReady) {
|
||||
this.rejectReady(new Error(line));
|
||||
this.rejectReady = undefined;
|
||||
}
|
||||
buff = buff.substring(regexArray[1].length + regexArray[2].length);
|
||||
regexArray = LINE_REGEX.exec(buff);
|
||||
|
@ -48,7 +48,7 @@ export class ArduinoVariableHandler {
|
||||
async getStaticVariables(frameHandle: number): Promise<DebugProtocol.Variable[]> {
|
||||
throw new Error('Static variables are not supported yet.');
|
||||
const frame = this.frameHandles.get(frameHandle);
|
||||
const result = await this.gdb.sendStackInfoFrame(this.gdb, frame.threadId, frame.frameId);
|
||||
const result = await this.gdb.sendStackInfoFrame(frame.threadId, frame.frameId);
|
||||
const file = path.normalize(result.frame.file || '');
|
||||
const symbolInfo: any[] = [] // this.symbolTable.getStaticVariables(file);
|
||||
const variables: DebugProtocol.Variable[] = [];
|
||||
|
Loading…
x
Reference in New Issue
Block a user