microsoft / vscode-cpptools

Official repository for the Microsoft C/C++ extension for VS Code.
Other
5.53k stars 1.56k forks source link

Running gdbserver as a `preLaunchTask` - need to press start/stop button several times #898

Open nikitablack opened 7 years ago

nikitablack commented 7 years ago
Extension Author (truncated) Version
vscode-docker Pet 0.0.16
tslint eg2 0.16.0
language-haskell jus 2.3.1
cpptools ms- 0.12.1
debugger-for-chrome msj 3.1.6
cmake twx 0.0.17
cmake-tools vec 0.10.2
debug web 0.20.0
c-cpp-snippets wlh 0.1.0

Hello. Thank you for the great tool - I'm using vscode/cpptools everyday and happy with it.

Now to the problem. I have the following task in tasks.json:

{
    "taskName": "docker build&run",
    "linux": {
        "args": [
            "\"docker run --rm --privileged -p 2222:2222 -v ~/path/:/path/ -w /path/build cpp_tools bash -c 'cmake --build . && gdbserver localhost:2222 ./app'\""
        ]
    },
    "group": {
        "kind": "build",
        "isDefault": true
    }
}

As you can see, it starts a docker container that builds an executable and runs gdbserver inside.

Here's my launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) remote",
            "type": "cppdbg",
            "request": "launch",
            "preLaunchTask": "docker build&run",
            "program": "${workspaceRoot}/build/app",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceRoot}/build",
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "miDebuggerServerAddress": "localhost:2222",
            "sourceFileMap": {
                "/path/": "~/path/"
            },
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

I want to build an app and start the debug session with F5 button. The problem is that I need to press F5 twice - the first press builds an app and starts the debug server in docker container and the second press launches my application (which successfully connects). The problem appears both for F5 and Start Debugging button in GUI. Also I have to press stop button 3 (three) times in order to stop an application (both for Shift+F5 and the Stop button in GUI).

pieandcakes commented 7 years ago

@nikitablack When you press F5 the first time do you see an error in the Debug Console? I'm trying to understand why you have to press it twice.

nikitablack commented 7 years ago

@pieandcakes There's no error, it just run the pre-launch task and not launches an app. Here I prepared a test project. There's a Dockerfile with compiler and gdbserver and the project (please change paths in tasks.json and launch.json).

P.S.: Something strange related to this issue - somehow in this project I see std::cout output in terminal window.

pieandcakes commented 7 years ago

@nikitablack I'll give that a shot. Thanks for providing a repro project.

JacobDomagala commented 7 years ago

I'm having the same issue. After pressing F5 for the first time, gdbserver starts listening on given port and nothing else happens (no vscode error, nothing). Then after pressing F5 for the second time, the debugging starts. However an error appears after the debugging ends "Unable to start debugging. Unexpected GDB output from command "-target-select remote localhost:10050". Remote communication error. Target disconnected.: Connection reset by peer.".

JelleRoets commented 6 years ago

problem with this approach (starting gdbserver as a prelaunch task) is that the debugger will only start when the prelaunch task has successfully exited (with return code 0). But the (prelaunch) task starting a gdbserver will of course not exit before you are finished debugging, as a consequence the debugger will wait forever to actually start and the gdbserver will wait until a gdb debugger connects => so both are waiting for each-other internally and nothing happens...

For this reason you have to startup a gdbserver on the remote manually as a seperate task and only afterwards launch a debugging session that will connect to the already running gdbserver.

However It would be very useful to start a gdbserver as a 'non-blocking' prelaunch task! Otherwise you have to do it manually every time again... Also it would be handy if the output of the gdbserver task could be redirected to the debugging terminal window. So you can debug a program remotely as if you would debug it locally.

Any suggestions / solutions? @pieandcakes ....

pieandcakes commented 6 years ago

@JelleRoets can you try and add & to your command to launch it and exit and not wait for it to terminate? Also, prelaunchtask is a VS Code feature and not one implemented by us so we don't control what happens.

JelleRoets commented 6 years ago

Unfortunately that doesn't help... When I just add the & to the gdbserver command in the prelaunchtask, gdbserver doesn't seem to startup well, and the debugger times out while trying to connect.

WardenGnaw commented 6 years ago

@JelleRoets I got it to work with the following schema.

{
   "command": "gdbserver",
   "args": [
      "localhost:2222",
      "./a.out",
      "&",
      "echo",
      "0"
   ],
   "isBackground": true
}
JelleRoets commented 6 years ago

specifying the "isBackground" option in the tasks.json is a good idea! However it still doesn't work smoothly on my side. When I do this the task is correctly compiling and uploading the code to the remote device and starts a gdbserver on the remote over ssh. However the VSCode debugger is still waiting and after while I got a message like: image

Pressing "Debug anyway" works, the VSCode debugger actually launches and I can debug correctly. However this is still not an ideal scenario and actually even worse than just running the command to upload and start gdb remotely manually and only next press the launch button....

If you'd be interested, this is my entire (example) project: https://github.com/JelleRoets/cross-compile-edison, the repo also contains the current .vscode setting files.

It would be nice to have a single button: to compile, upload and start a remote debugging session, however that doesn't seem possible unfortunately.

daniel-brosche commented 3 years ago

I have found a solution for me which is quite pragmatic.

I'm using the following preLaunchTask without the need of isBackground and regex patterns (to detect the begin and end of the task execution) by just starting gdbserver as background command/job combined with a little sleep:

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

In this example I have script ssh.py which is a small wrapper to encapsulate the establishment of the ssh connection. Internally it uses ssh or in combination of sshpass depending on my needs, like:

ssh -i ~/.ssh/key.rsa -p 22 root@172.31.207.88 'my_command'

or with sshpass

sshpass -p my_password ssh -p 22 root@172.31.207.88 'my_command'

and here my postDebug Task to shutdown gdbserver:

 {
            "label": "Shutdown GDB remote debugger",
            "type": "shell",
            "options": {
                "cwd": "${workspaceRoot}/"
            },
            "presentation": {
                "echo": true,
                "reveal": "always",
                "focus": false,
                "panel": "shared",
                "revealProblems": "onProblem"
            },
            "command": "clear;./ssh.py 'pkill -9 gdbserver'",
            "problemMatcher": []
        },

All togehther used with this launch configuration (also by using an external .gdbinit file to simplify my gdb configuration):

 {
        "name": "GDB Remote opc_ua_server",
        "type": "cppdbg",
        "request": "launch",
        "program": "${workspaceFolder}/build/myapp",
        "args": [],
        "miDebuggerPath": "${workspaceFolder}/tools/x86_64/bin/x86_64-lenze-linux-gnu-gdb",
        "miDebuggerServerAddress": "172.31.207.88:6666",
        "miDebuggerArgs": "-x ${workspaceFolder}/.gdbinit",
        "preLaunchTask": "Start GDB remote debugger",
        "postDebugTask": "Shutdown GDB remote debugger",
        "stopAtEntry": false,
        "cwd": "${workspaceFolder}/build/",
        "environment": [],
        "externalConsole": true,
        "MIMode": "gdb",
        "setupCommands": [
            {
                "description": "Enable pretty-printing for gdb",
                "text": "-enable-pretty-printing",
                "ignoreFailures": true
            }//,
            // {
            //     "description": "Ignore signal 40",
            //     "text": "handle SIG40 nostop noprint pass",
            //     "ignoreFailures": true
            // }
        ]
    },

This works quite stable, even on slow connections via vpn in my experience.

So it's quite easy to start a remote debugging session with just hitting F5 or the Start Debugging-Button

Btw: this approach also works in the same way with the lldb-server.

Since I have found this solution I'm so much more happy with my vscode Remote Debugging Experience.

Please feel free to share and thumb up.

dwlsalmeida commented 3 years ago

Hi there!

Any updates on this? :)

Facing the same issue here..

collinmccarthy commented 3 years ago

Facing the same issue as well, trying to run docker-compose up as a pre-launch task for attaching the python debugger:

From tasks.json:

{
    "type": "docker-compose",
    "label": "docker-compose: debug up",
    "dockerCompose": {
      "up": {
        "detached": true,
        "build": true,
        "services": ["app"]
      },
      "files": [
        "${workspaceFolder}/docker-compose.debug.yml"
      ]
    }
}

And from launch.json:

{
    "name": "Docker-Compose Debug",
    "type": "python",
    "request": "attach",
    "preLaunchTask": "docker-compose: debug up",
    "port": 5678,
    "host": "localhost",
    "pathMappings": [
        {
            "localRoot": "${workspaceFolder}",
            "remoteRoot": "/app"
        }
    ]
}

Starting debugging twice works (but not once) just like the OP. I understand why this is happening, but I'm hoping there's a way to fix this without any type of weird workaround. Thanks!

Deniffer commented 2 years ago

Facing with the same issue! but in my case it works in previous VS code version,since i reinstall the VS code, when i try to use the same task.json && lauch.json, it doesn't work anymore. It seems like it can not return the exit status 0 which indicate that the pretask execute successfully. Any help would be appreciated!

Deniffer commented 2 years ago

I have found a solution to solve these case , it does help in my case ,So i pasted my lauch.json && tasks.json,. lauch.json { "version": "0.2.0", "configurations": [ { "name": "debug xv6", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/kernel/kernel", "args": [], "stopAtEntry": true, "cwd": "${workspaceFolder}", "miDebuggerServerAddress": "localhost:26000", "miDebuggerPath": "/usr/bin/gdb-multiarch", "environment": [], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "pretty printing", "text": "-enable-pretty-printing", "ignoreFailures": true } ], "logging": { "engineLogging": true, "programOutput": true, }, "preLaunchTask": "build-extras", } ] }

task.json { // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { "label": "build-extras", "type": "shell", "isBackground": true, "command": "./build.sh",

    // This task is run before some debug tasks.
    // Problem is, it's a watch script, and since it never exits, VSCode
    // complains. All this is needed so VSCode just lets it run.
    "problemMatcher": [
      {
        "pattern": [
          {
            "regexp": ".",
            "file": 1,
            "location": 2,
            "message": 3
          }
        ],
        "background": {
          "activeOnStart": true,
          "beginsPattern": ".",
          "endsPattern": ".",
        }
      }
    ]
  }
]

}

maudieey commented 2 years ago

Facing with similar issue. I am debugging embeded target. I solved my problem by replacing

"command": "ssh root@192.168.1.1 'gdbserver :111 /home/root/my-app'",

with

"command": "setsid ssh root@192.168.1.1 'gdbserver :111 /home/root/my-app'",