debugging - VS Code 扩展调试器无法附加
问题描述
我正在编写基于sirmspencer 的 AutoHide的 VS Code 扩展,并且 > 90% 的调试尝试都失败了。
它启动并工作,但调试器似乎没有附加:
- 断点永远不会被命中,即使扩展主机正在运行它们
- 控制台输出未发送到调试控制台(非常烦人)
- 当我关闭测试窗口并终止进程时,调试器不会收到通知并继续运行
- 当我停止调试器时,测试窗口不会收到通知并保持打开状态
可能是什么问题呢?
[视频]
以下是.\.vscode
:
launch.json
中的文件
// A launch configuration that compiles the extension and then opens it inside a new window
{
"version": "0.1.0",
"configurations": [
{
"name": "Launch Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceRoot}" ],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [ "${workspaceRoot}/out/src/**/*.js" ],
"preLaunchTask": "npm"
},
{
"name": "Launch Tests",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [ "${workspaceRoot}/out/test/**/*.js" ],
"preLaunchTask": "npm"
}
]
}
settings.json
:
// Place your settings in this file to overwrite default and user settings.
{
"files.exclude": {
"out": false // set this to true to hide the "out" folder with the compiled JS files
},
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
}
}
tasks.json
:
// A task runner that calls a custom npm script that compiles the extension.
{
"version": "0.1.0",
// we want to run npm
"command": "npm",
// the command is a shell script
"isShellCommand": true,
// show the output window only if unrecognized errors occur.
"showOutput": "silent",
// we run the custom script "compile" as defined in package.json
"args": ["run", "compile", "--loglevel", "silent"],
// The tsc compiler is started in watching mode
"isWatching": true,
// use the standard tsc in watch mode problem matcher to find compile problems in the output.
"problemMatcher": "$tsc-watch"
}
我的package.json
:
{
"name": "vscode-hideEmptyErrors",
"displayName": "Hide Empty Problems Panel",
"description": "Hide the 'Problems' panel when there are no relevant errors",
"version": "1.0.0",
"publisher": "Black Platypus",
"repository": {
"url": "https://example.com"
},
"icon": "Images/Icons/Logo_512.png",
"engines": {
"vscode": "^1.43.0"
},
"extensionKind": [
"ui",
"workspace"
],
"categories": [
"Other"
],
"keywords": [
"problems",
"panel",
"hide",
"auto"
],
"activationEvents": [
"*"
],
"main": "./out/src/extension",
"contributes": {
"configuration": {
"type": "object",
"title": "hideEmptyErrors",
"properties": {
"hideEmptyErrors.autoHidePanel": {
"type": "boolean",
"default": true,
"description": "Hide the 'Problems' panel when there are no relevant errors."
},
"hideEmptyErrors.noEditorBehavior": {
"type": "string",
"description": "What should happen when there is no active editor or the active editor has no document while the Problems panel is active?",
"default": "No change",
"enum": [
"No change",
"Hide panel",
"Show Panel"
],
"enumDescriptions": [
"Keeps the panel's current state (visible/hidden)",
"Always hides the panel",
"Always shows the panel"
]
},
"hideEmptyErrors.onlyCountErrorsForCurrentFile": {
"type": "boolean",
"default": true,
"description": "Only count errors for the currently active editor's file."
}
}
},
"commands": [
{
"command": "hideEmptyErrors.toggleHidePanel",
"category": "Auto Hide",
"title": "Toggle Auto Hide Panel for Current Workspace"
}
]
},
"scripts": {
"compile": "tsc -watch -p ./",
"#test": "node ./node_modules/vscode/bin/test",
"vscode:prepublish": "tsc -p ./",
"#postinstall": "node ./node_modules/vscode/bin/install",
"publish": "vsce publish"
},
"devDependencies": {
"@types/mocha": "^2.2.32",
"@types/node": "7.0.7",
"mocha": "^7.2.0",
"typescript": "^2.9.2",
"vscode": "^1.1.36"
}
}
解决方案
我有同样的问题,症状完全相同,直到开发工具控制台中的“找不到用于调试的可用端口”警告。我怀疑这是由于极其严格的防火墙/防病毒软件造成的。似乎扩展开发主机试图找到一个 TCP 端口来与调试器客户端通信,但由于某种原因失败了。这是相关的代码段localProcessExtensionHost.ts
:
/**
* Find a free port if extension host debugging is enabled.
*/
private async _tryFindDebugPort(): Promise<number> {
if (typeof this._environmentService.debugExtensionHost.port !== 'number') {
return 0;
}
const expected = this._environmentService.debugExtensionHost.port;
const port = await findFreePort(expected, 10 /* try 10 ports */, 5000 /* try up to 5 seconds */);
if (!this._isExtensionDevTestFromCli) {
if (!port) {
console.warn('%c[Extension Host] %cCould not find a free port for debugging', 'color: blue', 'color:');
} else {
if (port !== expected) {
console.warn(`%c[Extension Host] %cProvided debugging port ${expected} is not free, using ${port} instead.`, 'color: blue', 'color:');
}
if (this._isExtensionDevDebugBrk) {
console.warn(`%c[Extension Host] %cSTOPPED on first line for debugging on port ${port}`, 'color: blue', 'color:');
} else {
console.info(`%c[Extension Host] %cdebugger listening on port ${port}`, 'color: blue', 'color:');
}
}
}
return port || 0;
}
事实证明,端口搜索findFreePort
从 in 给定的端口开始仅尝试十个左右的 TCP 端口this._environmentService.port
,默认值为 5870,如果我相信 in 的单元测试,您可以使用命令行参数覆盖该environmentService
端口environmentService.test.ts
:
assert.deepStrictEqual(parse([]), { port: 5870, break: false, debugId: undefined });
assert.deepStrictEqual(parse(['--debugPluginHost']), { port: 5870, break: false, debugId: undefined });
assert.deepStrictEqual(parse(['--debugPluginHost=1234']), { port: 1234, break: false, debugId: undefined });
assert.deepStrictEqual(parse(['--debugBrkPluginHost']), { port: 5870, break: false, debugId: undefined });
assert.deepStrictEqual(parse(['--debugBrkPluginHost=5678']), { port: 5678, break: true, debugId: undefined });
assert.deepStrictEqual(parse(['--debugPluginHost=1234', '--debugBrkPluginHost=5678', '--debugId=7']), { port: 5678, break: true, debugId: '7' });
总之,--debugPluginHost=PORT
使用 5870 以外的端口添加到您的启动配置似乎可以使调试工作。这是一个端口 1234 的示例,它最终为我修复了 hello world 示例:
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"args": [
"--debugPluginHost=1234",
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}"
},
您可能必须尝试使用端口号才能找到适合您的端口号。
推荐阅读
- javascript - 处理来自 Promises React Native 的多个响应
- amazon-web-services - 适用于 Android 后端的 AWS CLI 存储
- ios - 旋转时弹出窗口视图位置错误
- angular - 如何从输入中获取数据?
- sql - Redshift SQL 查询 - 优化
- tsql - 只是 Exec SP 工作,但插入表 Exec SP 进入无限循环
- c++ - R 4.0 无法在 MacOs Catalina 中编译 C 源代码,clang-7 错误
- sql - 将 SQL 与 group by 重叠
- linux-device-driver - 为wn722n编译驱动时出错是什么意思?
- javascript - 为什么 update() 在发送多个对象时会删除 firebase 中子项的先前数据?