mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-18 16:56:33 +00:00
Detect errors in spawned process
This commit is contained in:
parent
2d9fa5615b
commit
3ed72de810
@ -65,15 +65,6 @@ export class ArduinoDebugSession extends GDBDebugSession {
|
||||
}
|
||||
}
|
||||
|
||||
protected async stackTraceRequest(response: DebugProtocol.StackTraceResponse, args: DebugProtocol.StackTraceArguments): Promise<void> {
|
||||
try {
|
||||
|
||||
return super.stackTraceRequest(response, args);
|
||||
} catch (err) {
|
||||
this.sendErrorResponse(response, 1, err.message);
|
||||
}
|
||||
}
|
||||
|
||||
protected scopesRequest(response: DebugProtocol.ScopesResponse, args: DebugProtocol.ScopesArguments): void {
|
||||
try {
|
||||
const frame: FrameVariableReference = {
|
||||
|
@ -4,9 +4,15 @@ import { spawn } from 'child_process';
|
||||
import { GDBBackend } from 'cdt-gdb-adapter/dist/GDBBackend';
|
||||
import { MIFrameInfo } from 'cdt-gdb-adapter/dist/mi';
|
||||
import { ArduinoLaunchRequestArguments } from './arduino-debug-session';
|
||||
import { ArduinoParser } from './arduino-parser';
|
||||
|
||||
export class ArduinoGDBBackend extends GDBBackend {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.parser = new ArduinoParser(this);
|
||||
}
|
||||
|
||||
spawn(requestArgs: ArduinoLaunchRequestArguments): Promise<void> {
|
||||
if (!requestArgs.sketch) {
|
||||
throw new Error('Missing argument: sketch');
|
||||
@ -26,7 +32,7 @@ export class ArduinoGDBBackend extends GDBBackend {
|
||||
const proc = spawn(command, args);
|
||||
this.proc = proc;
|
||||
this.out = proc.stdin;
|
||||
return this.parser.parse(proc.stdout);
|
||||
return (this.parser as ArduinoParser).parseFull(proc);
|
||||
}
|
||||
|
||||
sendFileExecAndSymbols(): Promise<void> {
|
||||
|
@ -0,0 +1,65 @@
|
||||
import { ChildProcessWithoutNullStreams } from 'child_process';
|
||||
import { Readable } from 'stream';
|
||||
import { MIParser } from "cdt-gdb-adapter/dist/MIParser";
|
||||
|
||||
const READY_TIMEOUT = 7000;
|
||||
const LINE_REGEX = /(.*)(\r?\n)/;
|
||||
|
||||
export class ArduinoParser extends MIParser {
|
||||
|
||||
parseFull(proc: ChildProcessWithoutNullStreams): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
proc.on('error', reject);
|
||||
let ready = false;
|
||||
proc.on('exit', () => {
|
||||
if (!ready) {
|
||||
reject(new Error('The gdb debugger terminated unexpectedly.'));
|
||||
}
|
||||
});
|
||||
|
||||
const timeout = setTimeout(() => {
|
||||
reject(new Error(`No response from gdb after ${READY_TIMEOUT} ms.`));
|
||||
}, READY_TIMEOUT);
|
||||
this.waitReady = () => {
|
||||
ready = true;
|
||||
clearTimeout(timeout);
|
||||
resolve();
|
||||
}
|
||||
this.readInputStream(proc.stdout);
|
||||
this.readErrorStream(proc.stderr, reject);
|
||||
});
|
||||
}
|
||||
|
||||
private readInputStream(stream: Readable) {
|
||||
let buff = '';
|
||||
stream.on('data', chunk => {
|
||||
buff += chunk.toString();
|
||||
let regexArray = LINE_REGEX.exec(buff);
|
||||
while (regexArray) {
|
||||
this.line = regexArray[1];
|
||||
this.pos = 0;
|
||||
this.handleLine();
|
||||
buff = buff.substring(regexArray[1].length + regexArray[2].length);
|
||||
regexArray = LINE_REGEX.exec(buff);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private readErrorStream(stream: Readable, reject: (reason?: any) => void) {
|
||||
let buff = '';
|
||||
stream.on('data', chunk => {
|
||||
buff += chunk.toString();
|
||||
let regexArray = LINE_REGEX.exec(buff);
|
||||
while (regexArray) {
|
||||
const line = regexArray[1];
|
||||
this.gdb.emit('consoleStreamOutput', line + '\n', 'stderr');
|
||||
if (line.toLowerCase().startsWith('error')) {
|
||||
reject(new Error(line));
|
||||
}
|
||||
buff = buff.substring(regexArray[1].length + regexArray[2].length);
|
||||
regexArray = LINE_REGEX.exec(buff);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user