diff --git a/arduino-debugger-extension/src/node/arduino-debug-adapter-contribution.ts b/arduino-debugger-extension/src/node/arduino-debug-adapter-contribution.ts index 2c36bc33..ab383bf8 100644 --- a/arduino-debugger-extension/src/node/arduino-debug-adapter-contribution.ts +++ b/arduino-debugger-extension/src/node/arduino-debug-adapter-contribution.ts @@ -1,23 +1,12 @@ -import { injectable, inject } from 'inversify'; +import { injectable } from 'inversify'; import { DebugAdapterContribution, DebugAdapterExecutable, DebugAdapterSessionFactory } from '@theia/debug/lib/common/debug-model'; import { DebugConfiguration } from "@theia/debug/lib/common/debug-configuration"; import { MaybePromise } from "@theia/core/lib/common/types"; import { IJSONSchema, IJSONSchemaSnippet } from "@theia/core/lib/common/json-schema"; import * as path from 'path'; -import { BoardsService } from 'arduino-ide-extension/lib/common/protocol/boards-service'; -import { CoreService } from 'arduino-ide-extension/lib/common/protocol/core-service'; -import { FileSystem } from '@theia/filesystem/lib/common'; @injectable() export class ArduinoDebugAdapterContribution implements DebugAdapterContribution { - @inject(BoardsService) - protected readonly boardsService: BoardsService; - - @inject(CoreService) - protected readonly coreService: CoreService; - - @inject(FileSystem) - protected readonly fileSystem: FileSystem; type = "arduino"; @@ -39,26 +28,25 @@ export class ArduinoDebugAdapterContribution implements DebugAdapterContribution "description": "path to the sketch root ino file", "default": "${file}", }, - "runToMain": { - "description": "If enabled the debugger will run until the start of the main function.", - "type": "boolean", - "default": false - }, "fqbn": { "type": "string", "description": "Fully-qualified board name to debug on", "default": "" }, - + "runToMain": { + "description": "If enabled the debugger will run until the start of the main function.", + "type": "boolean", + "default": false + }, "verbose": { "type": "boolean", "description": "Produce verbose log output", - "default": "false" + "default": false }, "debugDebugAdapter": { "type": "boolean", "description": "Start the debug adapter in debug mode (with --inspect-brk)", - "default": "false" + "default": false }, } } @@ -74,7 +62,7 @@ export class ArduinoDebugAdapterContribution implements DebugAdapterContribution if (!!config.debugDebugAdapter) { args.push('--inspect-brk') } - args = args.concat([path.join(__dirname, 'debug-adapter', 'index.js')]); + args = args.concat([path.join(__dirname, 'debug-adapter', 'main')]); return { command: "node", @@ -88,25 +76,21 @@ export class ArduinoDebugAdapterContribution implements DebugAdapterContribution name: this.label, type: this.type, request: "launch", - sketch: "${file}", - - verbose: true, - runToMain: true, }, { name: this.label + " (explicit)", type: this.type, request: "launch", - + program: "${sketchBinary}", objdump: "${boardTools:objdump}", gdb: "${boardTools:gdb}", gdbServer: "${boardTools:openocd}", gdbServerArguments: ["-s", "${boardTools:openocd-scripts}", "--file", "${board:openocd-debug-file}"], - - verbose: true, - runToMain: true, + + runToMain: false, + verbose: false, } ]; } diff --git a/arduino-debugger-extension/src/node/debug-adapter/cmsis-debug-session.ts b/arduino-debugger-extension/src/node/debug-adapter/cmsis-debug-session.ts index 3ea4f243..0584a154 100644 --- a/arduino-debugger-extension/src/node/debug-adapter/cmsis-debug-session.ts +++ b/arduino-debugger-extension/src/node/debug-adapter/cmsis-debug-session.ts @@ -25,7 +25,7 @@ import { normalize } from 'path'; import { DebugProtocol } from 'vscode-debugprotocol'; -import { Logger, logger, InitializedEvent, OutputEvent, Scope, TerminatedEvent } from 'vscode-debugadapter'; +import { Logger, logger, InitializedEvent, OutputEvent, Scope, TerminatedEvent, ErrorDestination } from 'vscode-debugadapter'; import { GDBDebugSession, RequestArguments, FrameVariableReference, FrameReference } from 'cdt-gdb-adapter/dist/GDBDebugSession'; import { GDBBackend } from 'cdt-gdb-adapter/dist/GDBBackend'; import { CmsisBackend } from './cmsis-backend'; @@ -117,7 +117,6 @@ export class CmsisDebugSession extends GDBDebugSession { protected async setBreakPointsRequest(response: DebugProtocol.SetBreakpointsResponse, args: DebugProtocol.SetBreakpointsArguments): Promise { await super.setBreakPointsRequest(response, args); - return; } protected scopesRequest(response: DebugProtocol.ScopesResponse, args: DebugProtocol.ScopesArguments): void { @@ -224,13 +223,10 @@ export class CmsisDebugSession extends GDBDebugSession { this.gdb.on('notifyAsync', (resultClass, resultData) => this.handleGDBNotify(resultClass, resultData)); // gdb server has main info channel on stderr - this.gdbServer.on('stderr', data => { - this.sendEvent(new OutputEvent(data, 'stdout')) - }); - this.gdbServer.on('error', message => { - this.sendEvent(new TerminatedEvent()); - throw message; - }); + this.gdbServer.on('stderr', data => this.sendEvent(new OutputEvent(data, 'stdout'))); + const gdbServerErrors: any[] = [] + const gdbServerErrorAccumulator = (message: any) => gdbServerErrors.push(message); + this.gdbServer.on('error', gdbServerErrorAccumulator); try { this.symbolTable = new SymbolTable(args.program, args.objdump); @@ -264,12 +260,18 @@ export class CmsisDebugSession extends GDBDebugSession { this.sendEvent(new OutputEvent(`Starting debugger: ${JSON.stringify(args)}`)); await this.gdbServer.spawn(args); await this.spawn(args); + if (gdbServerErrors.length > 0) { + throw new Error(gdbServerErrors.join('\n')); + } // Send commands await mi.sendTargetAsyncOn(this.gdb); await mi.sendTargetSelectRemote(this.gdb, remote); await mi.sendMonitorResetHalt(this.gdb); this.sendEvent(new OutputEvent(`Attached to debugger on port ${port}`)); + if (gdbServerErrors.length > 0) { + throw new Error(gdbServerErrors.join('\n')); + } // Download image const progressListener = (percent: number) => this.progressEvent(percent, 'Loading Image'); @@ -287,8 +289,17 @@ export class CmsisDebugSession extends GDBDebugSession { await mi.sendBreakOnFunction(this.gdb); } + if (gdbServerErrors.length > 0) { + throw new Error(gdbServerErrors.join('\n')); + } this.sendEvent(new OutputEvent(`Image loaded: ${args.program}`)); this.sendEvent(new InitializedEvent()); + + this.gdbServer.removeListener('error', gdbServerErrorAccumulator); + this.gdbServer.on('error', message => { + logger.error(JSON.stringify(message)); + this.sendEvent(new TerminatedEvent()); + }); } private async getGlobalVariables(frameHandle: number): Promise { @@ -378,6 +389,15 @@ export class CmsisDebugSession extends GDBDebugSession { })); } + protected sendErrorResponse(response: DebugProtocol.Response, + codeOrMessage: number | DebugProtocol.Message, format?: string, + variables?: any, dest?: ErrorDestination): void { + if (!!format && (dest === undefined || dest === ErrorDestination.User)) { + format = format.replace('\n', '
'); + } + super.sendErrorResponse(response, codeOrMessage, format, variables, dest); + } + protected async stopSession() { // Pause debugging if (this.isRunning) { diff --git a/arduino-debugger-extension/src/node/debug-adapter/index.ts b/arduino-debugger-extension/src/node/debug-adapter/main.ts similarity index 100% rename from arduino-debugger-extension/src/node/debug-adapter/index.ts rename to arduino-debugger-extension/src/node/debug-adapter/main.ts diff --git a/arduino-debugger-extension/src/node/debug-adapter/openocd-server.ts b/arduino-debugger-extension/src/node/debug-adapter/openocd-server.ts index 079ddcb0..e574ce98 100644 --- a/arduino-debugger-extension/src/node/debug-adapter/openocd-server.ts +++ b/arduino-debugger-extension/src/node/debug-adapter/openocd-server.ts @@ -6,7 +6,7 @@ import * as path from 'path'; import * as os from 'os'; const LAUNCH_REGEX = /GDB server started/; -const ERROR_REGEX = /:ERROR:gdbserver:/; +const ERROR_REGEX = /^error:/mi; const PERCENT_MULTIPLIER = 100 / 40; // pyOCD outputs 40 markers for progress export class OpenocdServer extends AbstractServer { @@ -20,14 +20,14 @@ export class OpenocdServer extends AbstractServer { sessionConfigFile += `telnet_port ${telnetPort}${"\n"}` } sessionConfigFile += `echo "GDB server started"${"\n"}` - + const tmpdir = await fs.mkdtemp(path.join(os.tmpdir(), "arduino-debugger")); const sessionCfgPath = path.join(tmpdir, "gdb.cfg"); await fs.writeFile(sessionCfgPath, sessionConfigFile); let serverArguments = req.gdbServerArguments || []; serverArguments.push("--file", sessionCfgPath); - + return serverArguments; }