From 54bdc89465819ea70f6c6cb7592bafaef68dd576 Mon Sep 17 00:00:00 2001 From: Esben Haabendal Date: Mon, 25 Nov 2019 15:05:34 +0100 Subject: [PATCH 1/3] Add emacs and vi garbage files to .gitignore --- .gitignore | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 12624048..080f7ba8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,10 @@ out node_modules *.vsix -.vscode-test \ No newline at end of file +.vscode-test + +# Editor littering +*.swp +*.orig +*.rej +*~ From 2f9bdcba126808878bb5c1d51929ff2338829303 Mon Sep 17 00:00:00 2001 From: Esben Haabendal Date: Tue, 7 Jan 2020 13:16:57 +0100 Subject: [PATCH 2/3] Rename launch argument target to executable As the target argument for launch configurations is an executable, let's name it as such to avoid confusion. The target argument is deprecated but kept for backwards compatibility. --- package.json | 8 ++++++-- src/backend/mi2/mi2.ts | 20 ++++++++++---------- src/gdb.ts | 7 +++++-- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index ea44d57d..a97dda5b 100644 --- a/package.json +++ b/package.json @@ -73,13 +73,17 @@ "configurationAttributes": { "launch": { "required": [ - "target" + "executable" ], "properties": { - "target": { + "executable": { "type": "string", "description": "Path of executable" }, + "target": { + "type": "string", + "description": "Path of executable (DEPRECATED use executable argument instead)" + }, "arguments": { "type": "string", "description": "Arguments to append after the executable. You can also use pipes." diff --git a/src/backend/mi2/mi2.ts b/src/backend/mi2/mi2.ts index 5cbd8284..b39829e0 100644 --- a/src/backend/mi2/mi2.ts +++ b/src/backend/mi2/mi2.ts @@ -50,9 +50,9 @@ export class MI2 extends EventEmitter implements IBackend { } } - load(cwd: string, target: string, procArgs: string, separateConsole: string): Thenable { - if (!nativePath.isAbsolute(target)) - target = nativePath.join(cwd, target); + load(cwd: string, executable: string, procArgs: string, separateConsole: string): Thenable { + if (!nativePath.isAbsolute(executable)) + executable = nativePath.join(cwd, executable); return new Promise((resolve, reject) => { this.isSSH = false; const args = this.preargs.concat(this.extraargs || []); @@ -61,7 +61,7 @@ export class MI2 extends EventEmitter implements IBackend { this.process.stderr.on("data", this.stderr.bind(this)); this.process.on("exit", (() => { this.emit("quit"); }).bind(this)); this.process.on("error", ((err) => { this.emit("launcherror", err); }).bind(this)); - const promises = this.initCommands(target, cwd); + const promises = this.initCommands(executable, cwd); if (procArgs && procArgs.length) promises.push(this.sendCommand("exec-arguments " + procArgs)); if (process.platform == "win32") { @@ -181,20 +181,20 @@ export class MI2 extends EventEmitter implements IBackend { }); } - protected initCommands(target: string, cwd: string, ssh: boolean = false, attach: boolean = false) { + protected initCommands(executable: string, cwd: string, ssh: boolean = false, attach: boolean = false) { if (ssh) { - if (!path.isAbsolute(target)) - target = path.join(cwd, target); + if (!path.isAbsolute(executable)) + executable = path.join(cwd, executable); } else { - if (!nativePath.isAbsolute(target)) - target = nativePath.join(cwd, target); + if (!nativePath.isAbsolute(executable)) + executable = nativePath.join(cwd, executable); } const cmds = [ this.sendCommand("gdb-set target-async on", true), this.sendCommand("environment-directory \"" + escape(cwd) + "\"", true) ]; if (!attach) - cmds.push(this.sendCommand("file-exec-and-symbols \"" + escape(target) + "\"")); + cmds.push(this.sendCommand("file-exec-and-symbols \"" + escape(executable) + "\"")); if (this.prettyPrint) cmds.push(this.sendCommand("enable-pretty-printing")); diff --git a/src/gdb.ts b/src/gdb.ts index a8b547c7..c14aa983 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -6,6 +6,7 @@ import { SSHArguments, ValuesFormattingMode } from './backend/backend'; export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArguments { cwd: string; + executable: string; target: string; gdbpath: string; env: any; @@ -60,6 +61,8 @@ class GDBDebugSession extends MI2DebugSession { this.setValuesFormattingMode(args.valuesFormatting); this.miDebugger.printCalls = !!args.printCalls; this.miDebugger.debugOutput = !!args.showDevDebugOutput; + if (args.executable == undefined) + args.executable = args.target; // legacy compatibility if (args.ssh !== undefined) { if (args.ssh.forwardX11 === undefined) args.ssh.forwardX11 = true; @@ -74,7 +77,7 @@ class GDBDebugSession extends MI2DebugSession { this.isSSH = true; this.trimCWD = args.cwd.replace(/\\/g, "/"); this.switchCWD = args.ssh.cwd; - this.miDebugger.ssh(args.ssh, args.ssh.cwd, args.target, args.arguments, args.terminal, false).then(() => { + this.miDebugger.ssh(args.ssh, args.ssh.cwd, args.executable, args.arguments, args.terminal, false).then(() => { if (args.autorun) args.autorun.forEach(command => { this.miDebugger.sendUserInput(command); @@ -94,7 +97,7 @@ class GDBDebugSession extends MI2DebugSession { this.sendErrorResponse(response, 102, `Failed to SSH: ${err.toString()}`); }); } else { - this.miDebugger.load(args.cwd, args.target, args.arguments, args.terminal).then(() => { + this.miDebugger.load(args.cwd, args.executable, args.arguments, args.terminal).then(() => { if (args.autorun) args.autorun.forEach(command => { this.miDebugger.sendUserInput(command); From ded131d9cd235fc1181b3d1d4073c5accaeaee70 Mon Sep 17 00:00:00 2001 From: Esben Haabendal Date: Tue, 7 Jan 2020 15:01:40 +0100 Subject: [PATCH 3/3] Add support for using extended-remote with launch configurations This extends gdb launch configurations to support extended-remote. It can be used for remote debugging where code is compiled on host, and transferred and debugged on target using a remote gdbserver (or something else speaking GDB/MI). Note, this is not touching the code added in commit 318ece44cf3a ("Added special commands for extended-remote fix #91"), as that is only related to gdb attach configuration. --- package.json | 17 +++++++++++++++++ src/backend/mi2/mi2.ts | 18 +++++++++++++++--- src/gdb.ts | 3 ++- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index a97dda5b..34611a20 100644 --- a/package.json +++ b/package.json @@ -111,6 +111,10 @@ "description": "Additional arguments to pass to GDB", "default": [] }, + "extendedRemote": { + "type": "string", + "description": "gdbserver (extended-remote) to connect to (eg :2345)" + }, "valuesFormatting": { "type": "string", "description": "Set the way of showing variable values. 'disabled' - show value as is, 'parseText' - parse debuggers output text into structure, 'prettyPrinters' - enable debuggers custom pretty-printers if there are any", @@ -440,6 +444,19 @@ ] }, "valuesFormatting": "parseText" + }, + { + "label": "GDB: Debug on remote device", + "description": "Transfer program to and debug it on a remote device", + "body": { + "type": "gdb", + "request": "launch", + "name": "${3:Debug remote device}", + "extendedRemote": "${2:192.168.0.1:2345}", + "executable": "${1:./bin/executable.elf}", + "cwd": "^\"\\${workspaceRoot}\"" + }, + "valuesFormatting": "parseText" } ] }, diff --git a/src/backend/mi2/mi2.ts b/src/backend/mi2/mi2.ts index b39829e0..c7486aea 100644 --- a/src/backend/mi2/mi2.ts +++ b/src/backend/mi2/mi2.ts @@ -50,18 +50,30 @@ export class MI2 extends EventEmitter implements IBackend { } } - load(cwd: string, executable: string, procArgs: string, separateConsole: string): Thenable { + load(cwd: string, executable: string, procArgs: string, separateConsole: string, extendedRemote?: string): Thenable { if (!nativePath.isAbsolute(executable)) executable = nativePath.join(cwd, executable); return new Promise((resolve, reject) => { this.isSSH = false; - const args = this.preargs.concat(this.extraargs || []); + const args = this.preargs.concat(this.extraargs || [], [executable]); this.process = ChildProcess.spawn(this.application, args, { cwd: cwd, env: this.procEnv }); this.process.stdout.on("data", this.stdout.bind(this)); this.process.stderr.on("data", this.stderr.bind(this)); this.process.on("exit", (() => { this.emit("quit"); }).bind(this)); this.process.on("error", ((err) => { this.emit("launcherror", err); }).bind(this)); - const promises = this.initCommands(executable, cwd); + let promises; + if (extendedRemote !== undefined) { + let remoteExecutable = nativePath.basename(executable); + promises = [ + this.sendCommand(`set target-async on`, true), + this.sendCommand(`environment-directory "${escape(cwd)}"`, true), + this.sendCommand(`target-select extended-remote ${extendedRemote}`), + this.sendCommand(`target-file-put "${escape(executable)}" ${remoteExecutable}`), + this.sendCommand(`gdb-set remote exec-file ./${remoteExecutable}`) + ]; + } else + promises = this.initCommands(executable, cwd); + if (procArgs && procArgs.length) promises.push(this.sendCommand("exec-arguments " + procArgs)); if (process.platform == "win32") { diff --git a/src/gdb.ts b/src/gdb.ts index c14aa983..4119dfb7 100644 --- a/src/gdb.ts +++ b/src/gdb.ts @@ -13,6 +13,7 @@ export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArgum debugger_args: string[]; arguments: string; terminal: string; + extendedRemote: string; autorun: string[]; ssh: SSHArguments; valuesFormatting: ValuesFormattingMode; @@ -97,7 +98,7 @@ class GDBDebugSession extends MI2DebugSession { this.sendErrorResponse(response, 102, `Failed to SSH: ${err.toString()}`); }); } else { - this.miDebugger.load(args.cwd, args.executable, args.arguments, args.terminal).then(() => { + this.miDebugger.load(args.cwd, args.executable, args.arguments, args.terminal, args.extendedRemote).then(() => { if (args.autorun) args.autorun.forEach(command => { this.miDebugger.sendUserInput(command);