Skip to content

Run gdb commands before connection #97 #99

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 60 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,18 @@
},
"autorun": {
"type": "array",
"description": "GDB commands to run when starting to debug",
"description": "GDB commands to be run after connection",
"default": []
},
"autorunBefore": {
"type": "array",
"description": "GDB commands to be run before connection",
"default": [
"gdb-set target-async on",
"environment-directory \"$cwd\"",
"target-select $target"
]
},
"ssh": {
"required": [
"host",
Expand Down Expand Up @@ -218,9 +227,18 @@
},
"autorun": {
"type": "array",
"description": "GDB commands to run when starting to debug",
"description": "GDB commands to be run after connection",
"default": []
},
"autorunBefore": {
"type": "array",
"description": "GDB commands to be run before connection",
"default": [
"gdb-set target-async on",
"environment-directory \"$cwd\"",
"target-select remote $target"
]
},
"ssh": {
"required": [
"host",
Expand Down Expand Up @@ -463,9 +481,18 @@
},
"autorun": {
"type": "array",
"description": "lldb commands to run when starting to debug",
"description": "lldb commands to be run after connection",
"default": []
},
"autorunBefore": {
"type": "array",
"description": "lldb commands to be run before connection",
"default": [
"gdb-set target-async on",
"environment-directory \"$cwd\"",
"target-select $target"
]
},
"ssh": {
"required": [
"host",
Expand Down Expand Up @@ -568,8 +595,17 @@
},
"autorun": {
"type": "array",
"description": "lldb commands to run when starting to debug",
"description": "lldb commands to be run after connection",
"default": []
},
"autorunBefore": {
"type": "array",
"description": "lldb commands to be run before connection",
"default": [
"gdb-set target-async on",
"environment-directory \"$cwd\"",
"target-select $target"
]
}
}
}
Expand Down Expand Up @@ -700,8 +736,17 @@
},
"autorun": {
"type": "array",
"description": "mago commands to run when starting to debug",
"description": "mago commands to be run after connection",
"default": []
},
"autorunBefore": {
"type": "array",
"description": "mago commands to be run before connection",
"default": [
"gdb-set target-async on",
"environment-directory \"$cwd\"",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just having $cwd without the quotes and instead adding the quotes in the replace function would be a better idea I think because it makes the default more clean and it's more obvious to the user because there are no random quotes around it.

"target-select $target"
]
}
}
},
Expand Down Expand Up @@ -745,8 +790,17 @@
},
"autorun": {
"type": "array",
"description": "mago commands to run when starting to debug",
"description": "mago commands to be run after connection",
"default": []
},
"autorunBefore": {
"type": "array",
"description": "mago commands to be run before connection",
"default": [
"gdb-set target-async on",
"environment-directory \"$cwd\"",
"target-select $target"
]
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/backend/backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ export interface SSHArguments {
}

export interface IBackend {
load(cwd: string, target: string, procArgs: string, separateConsole: string): Thenable<any>;
ssh(args: SSHArguments, cwd: string, target: string, procArgs: string, separateConsole: string, attach: boolean): Thenable<any>;
attach(cwd: string, executable: string, target: string): Thenable<any>;
connect(cwd: string, executable: string, target: string): Thenable<any>;
load(cwd: string, target: string, autorunBeforeCmds: string[], procArgs: string, separateConsole: string): Thenable<any>;
ssh(args: SSHArguments, cwd: string, target: string, autorunBeforeCmds: string[], procArgs: string, separateConsole: string, attach: boolean): Thenable<any>;
attach(cwd: string, executable: string, target: string, autorunBeforeCmds: string[]): Thenable<any>;
connect(cwd: string, executable: string, target: string, autorunBeforeCmds: string[]): Thenable<any>;
start(): Thenable<boolean>;
stop();
detach();
Expand Down
53 changes: 25 additions & 28 deletions src/backend/mi2/mi2.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Breakpoint, IBackend, Stack, SSHArguments, Variable } from "../backend"
import { escape } from "../mi_parse"
import * as ChildProcess from "child_process"
import { EventEmitter } from "events"
import { parseMI, MINode } from '../mi_parse';
Expand All @@ -10,10 +11,6 @@ import * as nativePath from "path"
let path = posix;
var Client = require("ssh2").Client;

export function escape(str: string) {
return str.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
}

const nonOutput = /^(?:\d*|undefined)[\*\+\=]|[\~\@\&\^]/;
const gdbMatch = /(?:\d*|undefined)\(gdb\)/;
const numRegex = /\d+/;
Expand All @@ -31,7 +28,7 @@ export class MI2 extends EventEmitter implements IBackend {
super();
}

load(cwd: string, target: string, procArgs: string, separateConsole: string): Thenable<any> {
load(cwd: string, target: string, autorunBeforeCmds: string[], procArgs: string, separateConsole: string): Thenable<any> {
if (!nativePath.isAbsolute(target))
target = nativePath.join(cwd, target);
return new Promise((resolve, reject) => {
Expand All @@ -41,7 +38,7 @@ export class MI2 extends EventEmitter implements IBackend {
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));
let promises = this.initCommands(target, cwd);
let promises = this.initCommands(target, cwd, autorunBeforeCmds);
if (procArgs && procArgs.length)
promises.push(this.sendCommand("exec-arguments " + procArgs));
if (process.platform == "win32") {
Expand Down Expand Up @@ -72,7 +69,7 @@ export class MI2 extends EventEmitter implements IBackend {
});
}

ssh(args: SSHArguments, cwd: string, target: string, procArgs: string, separateConsole: string, attach: boolean): Thenable<any> {
ssh(args: SSHArguments, cwd: string, target: string, autorunBeforeCmds: string[], procArgs: string, separateConsole: string, attach: boolean): Thenable<any> {
return new Promise((resolve, reject) => {
this.isSSH = true;
this.sshReady = false;
Expand Down Expand Up @@ -143,7 +140,7 @@ export class MI2 extends EventEmitter implements IBackend {
this.emit("quit");
this.sshConn.end();
}).bind(this));
let promises = this.initCommands(target, cwd, true, attach);
let promises = this.initCommands(target, cwd, autorunBeforeCmds, true, attach);
promises.push(this.sendCommand("environment-cd \"" + escape(cwd) + "\""));
if (procArgs && procArgs.length && !attach)
promises.push(this.sendCommand("exec-arguments " + procArgs));
Expand All @@ -161,7 +158,8 @@ export class MI2 extends EventEmitter implements IBackend {
});
}

protected initCommands(target: string, cwd: string, ssh: boolean = false, attach: boolean = false) {
protected initCommands(target: string, cwd: string, autorunBeforeCmds: string[], ssh: boolean = false, attach: boolean = false) {
let cmds = [];
if (ssh) {
if (!path.isAbsolute(target))
target = path.join(cwd, target);
Expand All @@ -170,17 +168,17 @@ export class MI2 extends EventEmitter implements IBackend {
if (!nativePath.isAbsolute(target))
target = nativePath.join(cwd, target);
}
var cmds = [
this.sendCommand("gdb-set target-async on", true),
this.sendCommand("environment-directory \"" + escape(cwd) + "\"", true)
];
autorunBeforeCmds.forEach(command => {
cmds.push(this.sendCommand(command));
});
if (!attach)
cmds.push(this.sendCommand("file-exec-and-symbols \"" + escape(target) + "\""));
return cmds;
}

attach(cwd: string, executable: string, target: string): Thenable<any> {
attach(cwd: string, executable: string, target: string, autorunBeforeCmds: string[]): Thenable<any> {
return new Promise((resolve, reject) => {
let cmds = [];
let args = [];
if (executable && !nativePath.isAbsolute(executable))
executable = nativePath.join(cwd, executable);
Expand All @@ -196,39 +194,38 @@ export class MI2 extends EventEmitter implements IBackend {
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));
var commands = [
this.sendCommand("gdb-set target-async on"),
this.sendCommand("environment-directory \"" + escape(cwd) + "\"")
];
autorunBeforeCmds.forEach(command => {
cmds.push(this.sendCommand(command));
});

if (isExtendedRemote) {
commands.push(this.sendCommand("target-select " + target));
commands.push(this.sendCommand("file-symbol-file \"" + escape(executable) + "\""));
cmds.push(this.sendCommand("file-symbol-file \"" + escape(executable) + "\""));
}
Promise.all(commands).then(() => {
Promise.all(cmds).then(() => {
this.emit("debug-ready")
resolve();
}, reject);
});
}

connect(cwd: string, executable: string, target: string): Thenable<any> {
connect(cwd: string, executable: string, target: string, autorunBeforeCmds: string[]): Thenable<any> {
return new Promise((resolve, reject) => {
let commands = [];
let args = [];
if (executable && !nativePath.isAbsolute(executable))
executable = nativePath.join(cwd, executable);
if (executable)
args = args.concat([executable], this.preargs);
else
args = this.preargs;
args = this.preargs;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is a leading whitespace here

this.process = ChildProcess.spawn(this.application, args, { cwd: cwd });
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));
Promise.all([
this.sendCommand("gdb-set target-async on"),
this.sendCommand("environment-directory \"" + escape(cwd) + "\""),
this.sendCommand("target-select remote " + target)
]).then(() => {
autorunBeforeCmds.forEach(command => {
commands.push(this.sendCommand(command));
});
Promise.all(commands).then(() => {
this.emit("debug-ready")
resolve();
}, reject);
Expand Down
25 changes: 14 additions & 11 deletions src/backend/mi2/mi2lldb.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { MI2, escape } from "./mi2"
import { MI2 } from "./mi2"
import { escape } from "../mi_parse"
import { Breakpoint } from "../backend"
import * as ChildProcess from "child_process"
import { posix } from "path"
import * as nativePath from "path"
let path = posix;

export class MI2_LLDB extends MI2 {
protected initCommands(target: string, cwd: string, ssh: boolean = false, attach: boolean = false) {
protected initCommands(target: string, cwd: string, autorunBeforeCmds: string[], ssh: boolean = false, attach: boolean = false) {
let cmds = [];
if (ssh) {
if (!path.isAbsolute(target))
target = path.join(cwd, target);
Expand All @@ -15,25 +17,26 @@ export class MI2_LLDB extends MI2 {
if (!nativePath.isAbsolute(target))
target = nativePath.join(cwd, target);
}
var cmds = [
this.sendCommand("gdb-set target-async on")
];
autorunBeforeCmds.forEach(command => {
cmds.push(this.sendCommand(command));
});
if (!attach)
cmds.push(this.sendCommand("file-exec-and-symbols \"" + escape(target) + "\""));
return cmds;
}

attach(cwd: string, executable: string, target: string): Thenable<any> {
attach(cwd: string, executable: string, target: string, autorunBeforeCmds: string[]): Thenable<any> {
return new Promise((resolve, reject) => {
let cmds = [];
this.process = ChildProcess.spawn(this.application, this.preargs, { cwd: cwd });
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));
Promise.all([
this.sendCommand("gdb-set target-async on"),
this.sendCommand("file-exec-and-symbols \"" + escape(executable) + "\""),
this.sendCommand("target-attach " + target)
]).then(() => {
autorunBeforeCmds.forEach(command => {
cmds.push(this.sendCommand(command));
});
cmds.push(this.sendCommand("file-exec-and-symbols \"" + escape(executable) + "\""));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already in the autorunBeforeCmds

Promise.all(cmds).then(() => {
this.emit("debug-ready");
resolve();
}, reject);
Expand Down
4 changes: 4 additions & 0 deletions src/backend/mi_parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ export interface MIInfo {
resultRecords: { resultClass: string, results: [string, any][] };
}

export function escape(str: string) {
return str.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
}

var octalMatch = /^[0-7]{3}/;
function parseString(str: string): string {
var ret = new Buffer(str.length * 4);
Expand Down
Loading