Срыв при отладке с помощью gdbserver в VSCode - preLaunchTask 'docker gdb' не может быть отслежен.

Резюме

Я пытаюсь отлаживать программу на C ++ в образе докера (Ubuntu), используя VSCode в качестве IDE в моей хост-системе (OS X). После различных действий с задачами 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

И когда я запускаю сеанс отладки на хосте, я использую эту команду запуска, подключаю локальный gdb к докеру 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"
    }
]
}

Это определение предстартовой задачи; он использует 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"
        }
    ]
}

Когда я запускаю сеанс отладки, я немедленно получаю следующий результат, который и ожидался:

Процесс ./tests/ConfigurationTest.cpp_TestRunner создан; pid = 1167

Прослушивание порта 9091

На данный момент gdbserver готов к работе, и я бы хотел, чтобы VSCode запустил свой gdb. Но вместо этого VSCode ждет 10 секунд, прежде чем появится диалоговое окно с сообщением «PreLaunchTask« docker gdb »не может быть отслежен». Если я нажму «Все равно отладить», сеанс отладки возобновится, как ожидалось, и, похоже, работает нормально.

Что я пробовал

Время ожидания 10 секунд очень похоже на https://github.com/Microsoft/vscode/issues/37997, поэтому я попытался использовать taskMatcher с activeOnStart: true, как было предложено там. Это не подействовало.

Я подумал, что, возможно, проблема заключалась в том, что команда docker exec работала на переднем плане, а VSCode ждал ее возврата, поэтому я попытался выполнить docker exec с -d (режим отсоединения, работает в фоновом режиме) или просто добавление символа «&» в конец команды докера. Опять же, никакого эффекта.

Может ли кто-нибудь подсказать, что я могу сделать, чтобы избавиться от этого надоедливого 10-секундного ожидания?

Большое спасибо.


person geekydel    schedule 09.01.2018    source источник


Ответы (2)


Сегодня я столкнулся с той же проблемой, я пытался запустить тесты Mocha с помощью отладчика, а vscode ждал, пока отладчик завершит задачу preLaunch, что противоположно тому, что мне было нужно - задача открывает отладчик, поэтому он мне нужен работает в "фоновом режиме" - хотя эта конфигурация исправила это для меня.

launch.json

{
    "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"
    }
    ]
}

tasks.json

{
  // 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*"
              }
          },
        }
      }
  ]
}

Главное, на что следует обратить внимание, - это isBackground флаг, beginsPattern и endsPattern регулярные выражения, они сообщают «родительской» задаче запуска, что, когда xxx был напечатан на консоль из «дочернего», он завершен, и vscode может продолжить выполнение фактической задачи.

Возможно, это не та проблема, с которой вы столкнулись с тем, что используете приложение C ++, но я думаю, что это по тем же причинам.

person verymadmango    schedule 30.05.2018
comment
Также важно иметь pattern вместе с параметрами background, иначе это не сработает. Мне пришлось добавить наполнитель pattern что-то вроде "pattern": [ { "regexp": ".*", "file": 1, "location": 2, "message": 3 } ],, чтобы убедиться, что background beginsPattern и endsPattern привыкли. - person AlexIIP; 11.04.2019

Я нашел для себя довольно прагматичное решение.

Я использую следующую preLaunchTask без необходимости использования шаблонов isBackground и регулярных выражений (для определения начала и конца выполнения задачи), просто запустив gdbserver в качестве фоновой команды / задания в сочетании с небольшим сном:

{
            "label": "Start GDB remote debugger",
            "type": "shell",
            "options": {
                "cwd": "${workspaceRoot}/"
            },
            "presentation": {
                "echo": true,
                "reveal": "always",
                "focus": false,
                "panel": "shared",
                "revealProblems": "onProblem"
            },
            "command": "clear;./ssh.py 'cd /opt/bin/;(nohup gdbserver localhost:6666 myapp &);sleep 1'",
            "problemMatcher": []
        },

Полную конфигурацию gdbserver можно найти здесь

По моему опыту, это работает довольно стабильно даже при медленном подключении через vpn.

person Daniel Byte    schedule 04.12.2020