mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-19 01:06:39 +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 {
|
protected scopesRequest(response: DebugProtocol.ScopesResponse, args: DebugProtocol.ScopesArguments): void {
|
||||||
try {
|
try {
|
||||||
const frame: FrameVariableReference = {
|
const frame: FrameVariableReference = {
|
||||||
|
@ -4,9 +4,15 @@ import { spawn } from 'child_process';
|
|||||||
import { GDBBackend } from 'cdt-gdb-adapter/dist/GDBBackend';
|
import { GDBBackend } from 'cdt-gdb-adapter/dist/GDBBackend';
|
||||||
import { MIFrameInfo } from 'cdt-gdb-adapter/dist/mi';
|
import { MIFrameInfo } from 'cdt-gdb-adapter/dist/mi';
|
||||||
import { ArduinoLaunchRequestArguments } from './arduino-debug-session';
|
import { ArduinoLaunchRequestArguments } from './arduino-debug-session';
|
||||||
|
import { ArduinoParser } from './arduino-parser';
|
||||||
|
|
||||||
export class ArduinoGDBBackend extends GDBBackend {
|
export class ArduinoGDBBackend extends GDBBackend {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.parser = new ArduinoParser(this);
|
||||||
|
}
|
||||||
|
|
||||||
spawn(requestArgs: ArduinoLaunchRequestArguments): Promise<void> {
|
spawn(requestArgs: ArduinoLaunchRequestArguments): Promise<void> {
|
||||||
if (!requestArgs.sketch) {
|
if (!requestArgs.sketch) {
|
||||||
throw new Error('Missing argument: sketch');
|
throw new Error('Missing argument: sketch');
|
||||||
@ -26,7 +32,7 @@ export class ArduinoGDBBackend extends GDBBackend {
|
|||||||
const proc = spawn(command, args);
|
const proc = spawn(command, args);
|
||||||
this.proc = proc;
|
this.proc = proc;
|
||||||
this.out = proc.stdin;
|
this.out = proc.stdin;
|
||||||
return this.parser.parse(proc.stdout);
|
return (this.parser as ArduinoParser).parseFull(proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendFileExecAndSymbols(): Promise<void> {
|
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