mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-08 11:56:36 +00:00
Actual debugging works
This commit is contained in:
parent
3d6d2ce814
commit
ea5f528ef0
@ -27,9 +27,15 @@ export class ArduinoDebugAdapterContribution implements DebugAdapterContribution
|
|||||||
"description": "Path to the program to be launched",
|
"description": "Path to the program to be launched",
|
||||||
"default": "${workspaceFolder}/${command:askProgramPath}"
|
"default": "${workspaceFolder}/${command:askProgramPath}"
|
||||||
},
|
},
|
||||||
"arguments": {
|
"sketch": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Arguments for the program"
|
"description": "Path to the sketch folder",
|
||||||
|
"default": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
"fbqn": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Fully qualified board name of the debugging target",
|
||||||
|
"default": "unknown"
|
||||||
},
|
},
|
||||||
"runToMain": {
|
"runToMain": {
|
||||||
"description": "If enabled the debugger will run until the start of the main function.",
|
"description": "If enabled the debugger will run until the start of the main function.",
|
||||||
@ -75,7 +81,7 @@ export class ArduinoDebugAdapterContribution implements DebugAdapterContribution
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Start the debug adapter in debug mode (with --inspect-brk)",
|
"description": "Start the debug adapter in debug mode (with --inspect-brk)",
|
||||||
"default": "false"
|
"default": "false"
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -85,7 +91,7 @@ export class ArduinoDebugAdapterContribution implements DebugAdapterContribution
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
provideDebugAdapterExecutable?(config: DebugConfiguration): MaybePromise<DebugAdapterExecutable> {
|
provideDebugAdapterExecutable(config: DebugConfiguration): MaybePromise<DebugAdapterExecutable> {
|
||||||
let args: string[] = [];
|
let args: string[] = [];
|
||||||
if (!!config.debugDebugAdapter) {
|
if (!!config.debugDebugAdapter) {
|
||||||
args.push('--inspect-brk')
|
args.push('--inspect-brk')
|
||||||
|
@ -33,7 +33,6 @@ import { CmsisRequestArguments } from './cmsis-debug-session';
|
|||||||
const TIMEOUT = 1000 * 10; // 10 seconds
|
const TIMEOUT = 1000 * 10; // 10 seconds
|
||||||
|
|
||||||
export abstract class AbstractServer extends EventEmitter {
|
export abstract class AbstractServer extends EventEmitter {
|
||||||
|
|
||||||
protected process?: ChildProcess;
|
protected process?: ChildProcess;
|
||||||
protected outBuffer: string = '';
|
protected outBuffer: string = '';
|
||||||
protected errBuffer: string = '';
|
protected errBuffer: string = '';
|
||||||
@ -50,7 +49,7 @@ export abstract class AbstractServer extends EventEmitter {
|
|||||||
this.timer = setTimeout(() => this.onSpawnError(new Error('Timeout waiting for gdb server to start')), TIMEOUT);
|
this.timer = setTimeout(() => this.onSpawnError(new Error('Timeout waiting for gdb server to start')), TIMEOUT);
|
||||||
|
|
||||||
const command = args.gdbServer || 'gdb-server';
|
const command = args.gdbServer || 'gdb-server';
|
||||||
const serverArguments = await this.resolveServerArguments(args.gdbServerArguments);
|
const serverArguments = await this.resolveServerArguments(args);
|
||||||
this.process = spawn(command, serverArguments, {
|
this.process = spawn(command, serverArguments, {
|
||||||
cwd: dirname(command),
|
cwd: dirname(command),
|
||||||
});
|
});
|
||||||
@ -80,8 +79,8 @@ export abstract class AbstractServer extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async resolveServerArguments(serverArguments?: string[]): Promise<string[]> {
|
protected async resolveServerArguments(req: CmsisRequestArguments): Promise<string[]> {
|
||||||
return serverArguments || [];
|
return req.gdbServerArguments || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onExit(code: number, signal: string) {
|
protected onExit(code: number, signal: string) {
|
||||||
|
@ -29,16 +29,18 @@ import { Logger, logger, InitializedEvent, OutputEvent, Scope, TerminatedEvent }
|
|||||||
import { GDBDebugSession, RequestArguments, FrameVariableReference, FrameReference, ObjectVariableReference } from 'cdt-gdb-adapter/dist/GDBDebugSession';
|
import { GDBDebugSession, RequestArguments, FrameVariableReference, FrameReference, ObjectVariableReference } from 'cdt-gdb-adapter/dist/GDBDebugSession';
|
||||||
import { GDBBackend } from 'cdt-gdb-adapter/dist/GDBBackend';
|
import { GDBBackend } from 'cdt-gdb-adapter/dist/GDBBackend';
|
||||||
import { CmsisBackend } from './cmsis-backend';
|
import { CmsisBackend } from './cmsis-backend';
|
||||||
import { PyocdServer } from './pyocd-server';
|
// import { PyocdServer } from './pyocd-server';
|
||||||
import { PortScanner } from './port-scanner';
|
import { PortScanner } from './port-scanner';
|
||||||
import { SymbolTable } from './symbols';
|
import { SymbolTable } from './symbols';
|
||||||
import * as varMgr from 'cdt-gdb-adapter/dist/varManager';
|
import * as varMgr from 'cdt-gdb-adapter/dist/varManager';
|
||||||
import * as mi from './mi';
|
import * as mi from './mi';
|
||||||
|
import { OpenocdServer } from './openocd-server';
|
||||||
|
|
||||||
export interface CmsisRequestArguments extends RequestArguments {
|
export interface CmsisRequestArguments extends RequestArguments {
|
||||||
runToMain?: boolean;
|
runToMain?: boolean;
|
||||||
gdbServer?: string;
|
gdbServer?: string;
|
||||||
gdbServerArguments?: string[];
|
gdbServerArguments?: string[];
|
||||||
|
gdbServerPort?: number;
|
||||||
objdump?: string;
|
objdump?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +50,7 @@ const STATIC_HANDLES_FINISH = 0x01FFFF;
|
|||||||
|
|
||||||
export class CmsisDebugSession extends GDBDebugSession {
|
export class CmsisDebugSession extends GDBDebugSession {
|
||||||
|
|
||||||
protected gdbServer = new PyocdServer();
|
protected gdbServer = new OpenocdServer();
|
||||||
protected portScanner = new PortScanner();
|
protected portScanner = new PortScanner();
|
||||||
protected symbolTable!: SymbolTable;
|
protected symbolTable!: SymbolTable;
|
||||||
protected globalHandle!: number;
|
protected globalHandle!: number;
|
||||||
@ -110,6 +112,11 @@ export class CmsisDebugSession extends GDBDebugSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected async setBreakPointsRequest(response: DebugProtocol.SetBreakpointsResponse, args: DebugProtocol.SetBreakpointsArguments): Promise<void> {
|
||||||
|
await super.setBreakPointsRequest(response, args);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
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 = {
|
||||||
@ -245,10 +252,11 @@ export class CmsisDebugSession extends GDBDebugSession {
|
|||||||
if (!args.gdbServerArguments) {
|
if (!args.gdbServerArguments) {
|
||||||
args.gdbServerArguments = [];
|
args.gdbServerArguments = [];
|
||||||
}
|
}
|
||||||
args.gdbServerArguments.push('--port', port.toString());
|
args.gdbServerPort = port;
|
||||||
|
|
||||||
// Start gdb client and server
|
// Start gdb client and server
|
||||||
this.progressEvent(0, 'Starting Debugger');
|
this.progressEvent(0, 'Starting Debugger');
|
||||||
|
this.sendEvent(new OutputEvent(`Starting debugger: ${JSON.stringify(args)}`));
|
||||||
await this.gdbServer.spawn(args);
|
await this.gdbServer.spawn(args);
|
||||||
await this.spawn(args);
|
await this.spawn(args);
|
||||||
|
|
||||||
|
@ -42,8 +42,8 @@ export function sendTargetSelectRemote(gdb: GDBBackend, remote: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function sendTargetDownload(gdb: GDBBackend) {
|
export function sendTargetDownload(gdb: GDBBackend) {
|
||||||
const command = '-target-download';
|
// const command = '-target-download';
|
||||||
return gdb.sendCommand(command);
|
// return gdb.sendCommand(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sendBreakOnFunction(gdb: GDBBackend, fn: string = 'main') {
|
export function sendBreakOnFunction(gdb: GDBBackend, fn: string = 'main') {
|
||||||
|
@ -1,31 +1,33 @@
|
|||||||
import { AbstractServer } from './abstract-server';
|
import { AbstractServer } from './abstract-server';
|
||||||
import { PortScanner } from './port-scanner';
|
import { PortScanner } from './port-scanner';
|
||||||
|
import { CmsisRequestArguments } from './cmsis-debug-session';
|
||||||
|
import * as fs from 'fs-extra';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
const LAUNCH_REGEX = /GDB server started/;
|
const LAUNCH_REGEX = /GDB server started/;
|
||||||
const ERROR_REGEX = /:ERROR:gdbserver:/;
|
const ERROR_REGEX = /:ERROR:gdbserver:/;
|
||||||
const PERCENT_MULTIPLIER = 100 / 40; // pyOCD outputs 40 markers for progress
|
const PERCENT_MULTIPLIER = 100 / 40; // pyOCD outputs 40 markers for progress
|
||||||
|
|
||||||
export class OpenocdServer extends AbstractServer {
|
export class OpenocdServer extends AbstractServer {
|
||||||
|
|
||||||
protected portScanner = new PortScanner();
|
protected portScanner = new PortScanner();
|
||||||
protected progress = 0;
|
protected progress = 0;
|
||||||
|
|
||||||
protected async resolveServerArguments(serverArguments?: string[]): Promise<string[]> {
|
protected async resolveServerArguments(req: CmsisRequestArguments): Promise<string[]> {
|
||||||
if (!serverArguments) {
|
let sessionConfigFile = `gdb_port ${req.gdbServerPort!}${"\n"}`;
|
||||||
serverArguments = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const telnetPort = await this.portScanner.findFreePort(4444);
|
const telnetPort = await this.portScanner.findFreePort(4444);
|
||||||
|
if (!!telnetPort) {
|
||||||
if (!telnetPort) {
|
sessionConfigFile += `telnet_port ${telnetPort}${"\n"}`
|
||||||
return serverArguments;
|
|
||||||
}
|
}
|
||||||
|
sessionConfigFile += `echo "GDB server started"${"\n"}`
|
||||||
|
|
||||||
|
const tmpdir = await fs.mkdtemp("arduino-debugger");
|
||||||
|
const sessionCfgPath = path.join(tmpdir, "gdb.cfg");
|
||||||
|
await fs.writeFile(sessionCfgPath, sessionConfigFile);
|
||||||
|
|
||||||
return [
|
let serverArguments = req.gdbServerArguments || [];
|
||||||
...serverArguments,
|
serverArguments.push("--file", sessionCfgPath);
|
||||||
'--telnet-port',
|
|
||||||
telnetPort.toString()
|
return serverArguments;
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onStdout(chunk: string | Buffer) {
|
protected onStdout(chunk: string | Buffer) {
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
import { AbstractServer } from './abstract-server';
|
import { AbstractServer } from './abstract-server';
|
||||||
import { PortScanner } from './port-scanner';
|
import { PortScanner } from './port-scanner';
|
||||||
|
import { CmsisRequestArguments } from './cmsis-debug-session';
|
||||||
|
|
||||||
const LAUNCH_REGEX = /GDB server started/;
|
const LAUNCH_REGEX = /GDB server started/;
|
||||||
const ERROR_REGEX = /:ERROR:gdbserver:/;
|
const ERROR_REGEX = /:ERROR:gdbserver:/;
|
||||||
@ -35,22 +36,17 @@ export class PyocdServer extends AbstractServer {
|
|||||||
protected portScanner = new PortScanner();
|
protected portScanner = new PortScanner();
|
||||||
protected progress = 0;
|
protected progress = 0;
|
||||||
|
|
||||||
protected async resolveServerArguments(serverArguments?: string[]): Promise<string[]> {
|
protected async resolveServerArguments(req: CmsisRequestArguments): Promise<string[]> {
|
||||||
if (!serverArguments) {
|
let serverArguments = req.gdbServerArguments || [];
|
||||||
serverArguments = [];
|
|
||||||
}
|
serverArguments.push('--port', req.gdbServerPort!.toString())
|
||||||
|
|
||||||
const telnetPort = await this.portScanner.findFreePort(4444);
|
const telnetPort = await this.portScanner.findFreePort(4444);
|
||||||
|
if (!!telnetPort) {
|
||||||
if (!telnetPort) {
|
serverArguments.push('--telnet-port', telnetPort.toString())
|
||||||
return serverArguments;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return serverArguments;
|
||||||
...serverArguments,
|
|
||||||
'--telnet-port',
|
|
||||||
telnetPort.toString()
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onStdout(chunk: string | Buffer) {
|
protected onStdout(chunk: string | Buffer) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user