在 VSCode 中使用 gdbserver 进行调试时停顿 - “无法跟踪 preLaunchTask 'docker gdb'。”

gee*_*del 4 debugging gdbserver docker visual-studio-code vscode-tasks

概括

我正在尝试在 docker 映像 (Ubuntu) 中调试 C++ 程序,同时在我的主机系统 (OS X) 上使用 VSCode 作为 IDE。在对 gdbserver 和 VSCode 任务进行各种修补后,我现在能够成功运行调试器,但是每次启动调试会话时,VSCode 都会挂起 10 秒,然后报告错误消息:

“无法跟踪 preLaunchTask 'docker gdb'。”

如果我点击这个错误,我可以正常地完美调试,但是每次调试时都要等待 10 秒,这让我非常沮丧。

细节

我的 Docker 映像是通过以下方式启动的,因此我的源代码安装在“app”目录中。安全设置是我在 Stack Overflow 上的其他地方找到的,需要允许 gdbserver:

docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -it -v "$(pwd):/app" -w "/app" -p 9091:9091 {imageName} /bin/bash
Run Code Online (Sandbox Code Playgroud)

当我在主机上启动调试会话时,我使用这个启动命令,将本地 gdb 连接到 docker gdbserver,并运行一个预启动任务:

{
"version": "0.2.0",
"configurations": [
    {
        "name": "Remote unit test",
        "type": "cppdbg",
        "request": "launch",
        "program": "./tests/ConfigurationTest.cpp_TestRunner",
        "miDebuggerServerAddress": "localhost:9091",
        "args": [],
        "stopAtEntry": false,
        "cwd": "${workspaceRoot}",
        "environment": [],
        "externalConsole": true,
        "MIMode": "gdb",
        "preLaunchTask": "docker gdb"
    }
]
}
Run Code Online (Sandbox Code Playgroud)

这是启动前任务的定义;它使用 docker exec 杀死任何现有的 gdbserver 并在相关的可执行文件上启动一个新的:

{
"version": "2.0.0",
"tasks": [
    {
        "label":"docker gdb",
        "command": "docker exec {containerName} /bin/bash -c \"pkill gdbserver; gdbserver localhost:9091 ./tests/ConfigurationTest.cpp_TestRunner\"",
        "isBackground": true,
        "type": "shell"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

当我启动调试会话时,我立即得到以下输出,这是预期的:

进程 ./tests/ConfigurationTest.cpp_TestRunner 创建;pid = 1167

监听 9091 端口

此时,gdbserver 已准备就绪,我希望 VSCode 启动其 gdb。但是 VSCode 会等待 10 秒,然后才会弹出一个对话框,提示“无法跟踪 preLaunchTask 'docker gdb'。”'。如果我单击“无论如何调试”,调试会话将按预期恢复,并且似乎表现良好。

我试过什么

10 秒的等待时间听起来与https://github.com/Microsoft/vscode/issues/37997非常相似,所以我尝试使用带有“activeOnStart:true”的 issueMatcher,正如那里所建议的那样。这没有效果。

我想可能问题是 docker exec 命令在前台运行,而 VSCode 正在等待它返回,所以我尝试使用 -d(分离模式,在后台运行)执行 docker exec,或者只是在 docker 命令的末尾添加一个“&”。再次,没有效果。

谁能建议我能做些什么来摆脱这个烦人的 10 秒等待?

非常感谢。

ver*_*ngo 6

我今天遇到了同样的问题,我试图用调试器运行 Mocha 测试,vscode 正在等待调试器完成 preLaunch 任务,这与我需要的相反 - 任务暴露了调试器,所以我需要它在“后台”中运行 - 尽管如此,这个配置为我修复了它。

启动文件

{
    "version": "0.2.0",
    "configurations": [
    {
      "type": "node",
      "request": "attach",
      "name": "Docker: Attach to Mocha",
      "port": 5858,
      "address": "localhost",
      "localRoot": "${workspaceFolder}/server",
      "remoteRoot": "/usr/src/app/server",
      "protocol": "inspector",
      "preLaunchTask": "mocha-docker-debug"
    }
    ]
}
Run Code Online (Sandbox Code Playgroud)

任务文件

{
  // See https://go.microsoft.com/fwlink/?LinkId=733558
  // for the documentation about the tasks.json format
  "version": "2.0.0",
  "tasks": [
      {
        "label": "mocha-docker-debug",
        "type": "shell",
        "command": "docker exec up-ibe-server-node npm run test-debug",
        "group": "test",
        "isBackground": true,
        "presentation": {
          "reveal": "never"
        },
        "problemMatcher": {
          "owner": "mocha",
          "fileLocation": "relative",
          "pattern": [
            {
              "regexp": "^not\\sok\\s\\d+\\s(.*)$"
            },
            {
              "regexp": "\\s+(.*)$",
              "message": 1
            },
            {
              "regexp": "\\s+at\\s(.*):(\\d+):(\\d+)$",
              "file": 1,
              "line": 2,
              "column": 3
            }
          ],
          "background": {
              "activeOnStart": true,
              "beginsPattern":{
                  "regexp": "mocha*"
              },
              "endsPattern":{
                  "regexp": "Debugger listening*"
              }
          },
        }
      }
  ]
}
Run Code Online (Sandbox Code Playgroud)

这里要注意的主要事情是isBackground标志beginsPattern和正则endsPattern表达式,这告诉“父”启动任务,当 xxx 从“子”打印到控制台时,它已完成,vscode 可以继续执行实际任务。

这可能不是您在运行 C++ 应用程序时遇到的确切问题,但我认为出于相同的原因。

  • 拥有 `pattern` 和 `background` 参数也很重要,否则它将无法工作。我不得不添加一个填充物`pattern`,比如`"pattern": [ { "regexp": ".*", "file": 1, "location": 2, "message": 3 } ],` 只是为了确保使用 `background` `beginsPattern` 和 `endsPattern`。 (3认同)