forked from microsoft/vscode
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
move auto-attach into new built-in extension; fixes microsoft#53586
- Loading branch information
Showing
13 changed files
with
650 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
src/** | ||
tsconfig.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
{ | ||
"name": "debug-auto-launch", | ||
"displayName": "%displayName%", | ||
"description": "%description%", | ||
"version": "1.0.0", | ||
"publisher": "vscode", | ||
"engines": { | ||
"vscode": "^1.5.0" | ||
}, | ||
"activationEvents": [ | ||
"*" | ||
], | ||
"main": "./out/extension", | ||
"scripts": { | ||
"compile": "gulp compile-extension:debug-auto-launch", | ||
"watch": "gulp watch-extension:debug-auto-launch" | ||
}, | ||
"contributes": { | ||
"configuration": { | ||
"title": "Node debug", | ||
"properties": { | ||
"debug.node.autoAttach": { | ||
"scope": "window", | ||
"type": "string", | ||
"enum": [ | ||
"disabled", | ||
"on", | ||
"off" | ||
], | ||
"enumDescriptions": [ | ||
"%debug.node.autoAttach.disabled.description%", | ||
"%debug.node.autoAttach.on.description%", | ||
"%debug.node.autoAttach.off.description%" | ||
], | ||
"description": "%debug.node.autoAttach.description%", | ||
"default": "disabled" | ||
} | ||
} | ||
}, | ||
"commands": [ | ||
{ | ||
"command": "extension.node-debug.toggleAutoAttach", | ||
"title": "%toggle.auto.attach%", | ||
"category": "Debug" | ||
} | ||
] | ||
}, | ||
"dependencies": { | ||
"vscode-nls": "^3.2.4" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "8.0.33" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"displayName": "Node Debug Auto-attach", | ||
"description": "Helper for auto-attach feature when node-debug extensions are not active.", | ||
|
||
"debug.node.autoAttach.description": "Automatically attach node debugger when node.js was launched in debug mode from integrated terminal.", | ||
"debug.node.autoAttach.disabled.description": "Auto attach is disabled and not shown in status bar.", | ||
"debug.node.autoAttach.on.description": "Auto attach is active.", | ||
"debug.node.autoAttach.off.description": "Auto attach is inactive.", | ||
|
||
"toggle.auto.attach": "Toggle Auto Attach" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/*--------------------------------------------------------------------------------------------- | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*--------------------------------------------------------------------------------------------*/ | ||
|
||
'use strict'; | ||
|
||
import * as vscode from 'vscode'; | ||
import * as nls from 'vscode-nls'; | ||
import { basename } from 'path'; | ||
import { pollProcesses, attachToProcess } from './nodeProcessTree'; | ||
|
||
const localize = nls.loadMessageBundle(); | ||
|
||
export function startAutoAttach(rootPid: number): vscode.Disposable { | ||
|
||
return pollProcesses(rootPid, true, (pid, cmdPath, args) => { | ||
const cmdName = basename(cmdPath, '.exe'); | ||
if (cmdName === 'node') { | ||
const name = localize('process.with.pid.label', "Process {0}", pid); | ||
attachToProcess(undefined, name, pid, args); | ||
} | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
/*--------------------------------------------------------------------------------------------- | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*--------------------------------------------------------------------------------------------*/ | ||
|
||
'use strict'; | ||
|
||
import * as vscode from 'vscode'; | ||
import * as nls from 'vscode-nls'; | ||
import { basename } from 'path'; | ||
import { pollProcesses, attachToProcess } from './nodeProcessTree'; | ||
|
||
const localize = nls.loadMessageBundle(); | ||
const ON_TEXT = localize('status.text.auto.attach.on', "Auto Attach: On"); | ||
const OFF_TEXT = localize('status.text.auto.attach.off', "Auto Attach: Off"); | ||
|
||
const TOGGLE_COMMAND = 'extension.node-debug.toggleAutoAttach'; | ||
|
||
let currentState: string; | ||
let autoAttacher: vscode.Disposable | undefined; | ||
let statusItem: vscode.StatusBarItem | undefined = undefined; | ||
|
||
|
||
export function activate(context: vscode.ExtensionContext): void { | ||
|
||
context.subscriptions.push(vscode.commands.registerCommand(TOGGLE_COMMAND, toggleAutoAttach)); | ||
|
||
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(e => { | ||
if (e.affectsConfiguration('debug.node.autoAttach')) { | ||
updateAutoAttachInStatus(context); | ||
} | ||
})); | ||
|
||
updateAutoAttachInStatus(context); | ||
} | ||
|
||
export function deactivate(): void { | ||
} | ||
|
||
|
||
function toggleAutoAttach(context: vscode.ExtensionContext) { | ||
|
||
const conf = vscode.workspace.getConfiguration('debug.node'); | ||
|
||
let value = conf.get('autoAttach'); | ||
if (value === 'on') { | ||
value = 'off'; | ||
} else { | ||
value = 'on'; | ||
} | ||
|
||
const info = conf.inspect('autoAttach'); | ||
let target: vscode.ConfigurationTarget = vscode.ConfigurationTarget.Global; | ||
if (info) { | ||
if (info.workspaceFolderValue) { | ||
target = vscode.ConfigurationTarget.WorkspaceFolder; | ||
} else if (info.workspaceValue) { | ||
target = vscode.ConfigurationTarget.Workspace; | ||
} else if (info.globalValue) { | ||
target = vscode.ConfigurationTarget.Global; | ||
} else if (info.defaultValue) { | ||
// setting not yet used: store setting in workspace | ||
if (vscode.workspace.workspaceFolders) { | ||
target = vscode.ConfigurationTarget.Workspace; | ||
} | ||
} | ||
} | ||
conf.update('autoAttach', value, target); | ||
|
||
updateAutoAttachInStatus(context); | ||
} | ||
|
||
function updateAutoAttachInStatus(context: vscode.ExtensionContext) { | ||
|
||
const newState = <string>vscode.workspace.getConfiguration('debug.node').get('autoAttach'); | ||
|
||
if (newState !== currentState) { | ||
|
||
currentState = newState; | ||
|
||
if (newState === 'disabled') { | ||
|
||
// turn everything off | ||
if (statusItem) { | ||
statusItem.hide(); | ||
statusItem.text = OFF_TEXT; | ||
} | ||
if (autoAttacher) { | ||
autoAttacher.dispose(); | ||
autoAttacher = undefined; | ||
} | ||
|
||
} else { // 'on' or 'off' | ||
|
||
// make sure status bar item exists and is visible | ||
if (!statusItem) { | ||
statusItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); | ||
statusItem.command = TOGGLE_COMMAND; | ||
statusItem.text = OFF_TEXT; | ||
statusItem.tooltip = localize('status.tooltip.auto.attach', "Automatically attach to node.js processes in debug mode"); | ||
statusItem.show(); | ||
context.subscriptions.push(statusItem); | ||
} else { | ||
statusItem.show(); | ||
} | ||
|
||
if (newState === 'off') { | ||
statusItem.text = OFF_TEXT; | ||
if (autoAttacher) { | ||
autoAttacher.dispose(); | ||
autoAttacher = undefined; | ||
} | ||
} else if (newState === 'on') { | ||
statusItem.text = ON_TEXT; | ||
const vscode_pid = process.env['VSCODE_PID']; | ||
const rootPid = vscode_pid ? parseInt(vscode_pid) : 0; | ||
autoAttacher = startAutoAttach(rootPid); | ||
} | ||
} | ||
} | ||
} | ||
|
||
function startAutoAttach(rootPid: number): vscode.Disposable { | ||
|
||
return pollProcesses(rootPid, true, (pid, cmdPath, args) => { | ||
const cmdName = basename(cmdPath, '.exe'); | ||
if (cmdName === 'node') { | ||
const name = localize('process.with.pid.label', "Process {0}", pid); | ||
attachToProcess(undefined, name, pid, args); | ||
} | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/*--------------------------------------------------------------------------------------------- | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for license information. | ||
*--------------------------------------------------------------------------------------------*/ | ||
|
||
'use strict'; | ||
|
||
import * as vscode from 'vscode'; | ||
import { getProcessTree, ProcessTreeNode } from './processTree'; | ||
import { analyseArguments } from './protocolDetection'; | ||
|
||
const pids = new Set<number>(); | ||
|
||
const POLL_INTERVAL = 1000; | ||
|
||
/** | ||
* Poll for all subprocesses of given root process. | ||
*/ | ||
export function pollProcesses(rootPid: number, inTerminal: boolean, cb: (pid: number, cmd: string, args: string) => void): vscode.Disposable { | ||
|
||
let stopped = false; | ||
|
||
function poll() { | ||
//const start = Date.now(); | ||
findChildProcesses(rootPid, inTerminal, cb).then(_ => { | ||
//console.log(`duration: ${Date.now() - start}`); | ||
setTimeout(_ => { | ||
if (!stopped) { | ||
poll(); | ||
} | ||
}, POLL_INTERVAL); | ||
}); | ||
} | ||
|
||
poll(); | ||
|
||
return new vscode.Disposable(() => stopped = true); | ||
} | ||
|
||
export function attachToProcess(folder: vscode.WorkspaceFolder | undefined, name: string, pid: number, args: string, baseConfig?: vscode.DebugConfiguration) { | ||
|
||
if (pids.has(pid)) { | ||
return; | ||
} | ||
pids.add(pid); | ||
|
||
const config: vscode.DebugConfiguration = { | ||
type: 'node', | ||
request: 'attach', | ||
name: name, | ||
stopOnEntry: false | ||
}; | ||
|
||
if (baseConfig) { | ||
// selectively copy attributes | ||
if (baseConfig.timeout) { | ||
config.timeout = baseConfig.timeout; | ||
} | ||
if (baseConfig.sourceMaps) { | ||
config.sourceMaps = baseConfig.sourceMaps; | ||
} | ||
if (baseConfig.outFiles) { | ||
config.outFiles = baseConfig.outFiles; | ||
} | ||
if (baseConfig.sourceMapPathOverrides) { | ||
config.sourceMapPathOverrides = baseConfig.sourceMapPathOverrides; | ||
} | ||
if (baseConfig.smartStep) { | ||
config.smartStep = baseConfig.smartStep; | ||
} | ||
if (baseConfig.skipFiles) { | ||
config.skipFiles = baseConfig.skipFiles; | ||
} | ||
if (baseConfig.showAsyncStacks) { | ||
config.sourceMaps = baseConfig.showAsyncStacks; | ||
} | ||
if (baseConfig.trace) { | ||
config.trace = baseConfig.trace; | ||
} | ||
} | ||
|
||
let { usePort, protocol, port } = analyseArguments(args); | ||
if (usePort) { | ||
config.processId = `${protocol}${port}`; | ||
} else { | ||
if (protocol && port > 0) { | ||
config.processId = `${pid}${protocol}${port}`; | ||
} else { | ||
config.processId = pid.toString(); | ||
} | ||
} | ||
|
||
vscode.debug.startDebugging(folder, config); | ||
} | ||
|
||
function findChildProcesses(rootPid: number, inTerminal: boolean, cb: (pid: number, cmd: string, args: string) => void): Promise<void> { | ||
|
||
function walker(node: ProcessTreeNode, terminal: boolean, renderer: number) { | ||
|
||
if (node.args.indexOf('--type=terminal') >= 0 && (renderer === 0 || node.ppid === renderer)) { | ||
terminal = true; | ||
} | ||
|
||
let { protocol } = analyseArguments(node.args); | ||
if (terminal && protocol) { | ||
cb(node.pid, node.command, node.args); | ||
} | ||
|
||
for (const child of node.children || []) { | ||
walker(child, terminal, renderer); | ||
} | ||
} | ||
|
||
function finder(node: ProcessTreeNode, pid: number): ProcessTreeNode | undefined { | ||
if (node.pid === pid) { | ||
return node; | ||
} | ||
for (const child of node.children || []) { | ||
const p = finder(child, pid); | ||
if (p) { | ||
return p; | ||
} | ||
} | ||
return undefined; | ||
} | ||
|
||
return getProcessTree(rootPid).then(tree => { | ||
if (tree) { | ||
|
||
// find the pid of the renderer process | ||
const extensionHost = finder(tree, process.pid); | ||
let rendererPid = extensionHost ? extensionHost.ppid : 0; | ||
|
||
for (const child of tree.children || []) { | ||
walker(child, !inTerminal, rendererPid); | ||
} | ||
} | ||
}); | ||
} |
Oops, something went wrong.