remote debugging

pull/142/head
Christian Toepfer 6 years ago
parent 7a02019b72
commit cd25036ef1

@ -70,6 +70,10 @@ export interface FileSystemConfig extends ConnectConfig {
_location?: ConfigLocation;
/* Internal property keeping track of where this config comes from (including merges) */
_locations: ConfigLocation[];
/* Debug port to attach */
debugPort?: number;
/* Task to run before debug session starts. SSH command: e.g. `/opt/vistec/python/bin/python -m ptvsd --host ${config.host} --port ${config.debugPort} --wait ${file}` */
debugPreLaunch?: string;
}
export function invalidConfigName(name: string) {

@ -146,6 +146,89 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid
}
root = root.replace(/^~/, home.replace(/\/$/, ''));
}
vscode.debug.registerDebugConfigurationProvider("*", {
resolveDebugConfiguration(folder: vscode.WorkspaceFolder, debugConfig: vscode.DebugConfiguration) {
if ((folder.uri.scheme === 'ssh') && config) {
debugConfig['request'] = 'attach';
debugConfig['pathMappings'] = [];
debugConfig['pathMappings'].push({ 'localRoot': 'ssh://' + config.name, 'remoteRoot': config.root });
if (config.debugPort) {
if (debugConfig['port'] && (debugConfig['port'] !== config.port))
Logging.warning(`Invalid port in 'launch.json' working on '${config.name}'`);
debugConfig['port'] = config.debugPort;
if (debugConfig['host'] && (debugConfig['host'] !== config.host))
Logging.warning(`Invalid host in 'launch.json' working on '${config.name}'`);
debugConfig['host'] = config.host;
}
if (debugConfig['port'] === undefined)
Logging.error(`Missing property "debugPort" for remote debugging on '${config.name}'`);
let workspaceFolder = root;
let file = "${file}"; // default to get error message to open an editor
if (vscode.window.activeTextEditor)
file = root + vscode.window.activeTextEditor.document.uri.path; // '${file}' can not be resolved per default
if (debugConfig['program'])
debugConfig['program'] = eval('`' + debugConfig['program'] + '`'); // resolve ${file}, ${workspaceFolder}
else
debugConfig['program'] = file;
}
return debugConfig;
}
});
vscode.debug.registerDebugAdapterTrackerFactory('*', {
createDebugAdapterTracker(session: vscode.DebugSession) {
if (config && config.debugPreLaunch) {
return {
onWillStartSession: () => {
if (config && config.debugPreLaunch) {
const file = session.configuration['program'];
const command = eval('`' + config.debugPreLaunch + '`'); // resolve ${file} and config.
new Promise((resolve, reject) => {
Logging.info(`Start preLaunch Task for remote debugging: ${command}`);
client.exec(command, (err, stream) => {
if (err) return reject(err);
stream.stderr.on('data', (d) => {
Logging.error(`Stderr from remote debugging: ${d}`);
})
stream.on('data', (d) => {
Logging.debug(`Stdout from remote debugging: ${d}`);
})
stream.on('error', reject);
stream.on('close', (exitCode, signal) => {
if (exitCode || signal) {
return reject(new Error("error listing directory"));
}
resolve();
});
});
});
}}};
}}
});
vscode.debug.registerDebugAdapterTrackerFactory('*', {
createDebugAdapterTracker(session: vscode.DebugSession) {
if (session.configuration['dapTrace']) {
return {
onWillStartSession: () => console.log(`start: ${session.id}`),
onWillReceiveMessage: m => console.log(`===> ${JSON.stringify(m, undefined, 2)}`),
onDidSendMessage: m => console.log(`<=== ${JSON.stringify(m, undefined, 2)}`),
onWillStopSession: () => console.log(`stop: ${session.id}`),
onError: err => console.log(`error: ${err}`),
onExit: (code, signal) => console.log(`exit: ${code}`)
};
}
}
});
const sftp = await getSFTP(client, config);
const fs = new SSHFileSystem(name, sftp, root, config!);
Logging.info(`Created SSHFileSystem for ${name}, reading root directory...`);

@ -100,5 +100,18 @@ export function passphrase(config: FileSystemConfig, onChange: FSCChanged<'passp
return <FieldDropdownWithInput key="passphrase" label="Passphrase" {...{ value, values, description }} onChange={callback} optional={true} />
}
export function debugPort(config: FileSystemConfig, onChange: FSCChanged<'debugPort'>): React.ReactElement {
const callback = (value?: number) => onChange('debugPort', value);
const description = 'Debug port to attach';
return <FieldNumber key="debugPort" label="Debug port" value={config.debugPort} onChange={callback} optional={true} description={description} />
}
export function debugPreLaunch(config: FileSystemConfig, onChange: FSCChanged<'debugPreLaunch'>): React.ReactElement {
const callback = (value?: string) => onChange('debugPreLaunch', value);
const description = 'Task to run before debug session starts. SSH command: e.g. `/opt/vistec/python/bin/python -m ptvsd --host ${config.host} --port ${config.debugPort} --wait ${file}`';
return <FieldString key="debugPreLaunch" label="Debug Launch" value={config.debugPreLaunch} onChange={callback} optional={true} description={description} />
}
type FieldFactory = (config: FileSystemConfig, onChange: FSCChanged) => React.ReactElement;
export const FIELDS: FieldFactory[] = [name, merge, label, putty, host, port, root, agent, username, password, privateKeyPath, passphrase];
export const FIELDS: FieldFactory[] = [name, merge, label, putty, host, port, root, agent, username, password, privateKeyPath, passphrase, debugPort, debugPreLaunch];

@ -43,7 +43,7 @@ export function groupByLocation(configs: FileSystemConfig[]): Array<[ConfigLocat
}
export interface FileSystemConfig extends ConnectConfig {
/* Name of the config. Can only exists of lowercase alphanumeric characters, slashes and any of these: _.+-@ */
/* Name of the config. Can only exists of lowercase alphanumeric characters, slashes and any of these: _.+-@ */
name: string;
/* Optional label to display in some UI places (e.g. popups) */
label?: string;
@ -69,6 +69,10 @@ export interface FileSystemConfig extends ConnectConfig {
_location?: ConfigLocation;
/* Internal property keeping track of where this config comes from (including merges) */
_locations: ConfigLocation[];
/* Debug port to attach */
debugPort?: number;
/* Task to run before debug session starts. SSH command: e.g. `/opt/vistec/python/bin/python -m ptvsd --host ${config.host} --port ${config.debugPort} --wait ${file}` */
debugPreLaunch?: string;
}
export function invalidConfigName(name: string) {

Loading…
Cancel
Save