WebFreak001 / code-debug

Native debugging for VSCode
The Unlicense
400 stars 114 forks source link

gdbserver + ssh tunnel? #377

Open infn-ke opened 1 year ago

infn-ke commented 1 year ago

Is there a way to setup an ssh tunnel to the target before gdb tries to connect to my gdbserver on the target?

My target is on a private IP address so need to setup an ssh tunnel via a jump host to reach to it. Not clear from reading the docs if this is possible with the ssh configuration.

GitMensch commented 1 year ago

If I remember correctly this is note "directly" supported, but it should be possible by a remote ssh configuration (to your jump host) and then connect from there to gdbserver on a possible different machine reachable from there.

infn-ke commented 1 year ago

Can vscode setup the ssh tunnel for me? If possible, how do I do that? All config goes to launch.json? Or I need to have a tasks.json setting up the tunnel and then the launch.json using that tunnel?

GitMensch commented 1 year ago

vscode can set up the tunnel if you use a remote workspace over ssh (in this case the debugger starts there), but that's not what you wanted with the proxy (it would mean you need the sources there).

This extension allows debugging over ssh and maps the sources, so this seems to be reasonable. (you'd definitely need the sources on the remote=proxy if you want that information in the debugger console, but otherwise it is likely not needed)

That would be a launch configuration similar to the following:

    {
        "name": "gdb pseudo proxy",
        "type": "gdb",
        "request": "launch",
        // commonly you need only a direct path substitution by the extension
        // from the local cwd to whatever is seen on the target
        "cwd": "",
        // we launch "something" on the proxy, it isn't important what (_maybe_ can be empty)
        "target": "less",
        // here comes the magic:
        "autorun": [
                "target extended-remote yourserver:port",
                // either: "attach 12345"  or
                "run some-prog arg1 arg2"
        ],
        // if source paths changed between compile and run
        // "pathSubstitutions": {   },
        "ssh": {"host": "your_proxy",
            // "user": "${input:user}", "password": "${input:pass}", 
            "user": "${env:USER}", "keyfile": "/home/${env:USER}/.ssh/id_rsa",
            // set this to the single main path if you only have one / no explicit mapping:
            "cwd":".".
            // or this if you need to map multiple paths
            //"sourceFileMap": {
            //  "${workspaceFolder:src}": "/some/path/on/the/final/target"
            //},
        },
        "stopAtEntry": true,                
        "printCalls": true, "showDevDebugOutput": true,
        "valuesFormatting": "prettyPrinters",
    },
GitMensch commented 1 year ago

Note: there was #223 to add a single proxy into this extension; it now should be possible to do that "more directly" with using the current ssh2 functions, even with an unlimited amount of proxies, there just needs to be someone that implements this. I'd mentor /comment on this change but am currently too involved in other projects to do that coding.

infn-ke commented 1 year ago

Thanks for the details here, not sure I understood all of it yet :-)

But wouldn't it be possible to have preLaunchTask to setup the ssh tunnel and start gdbserver on the target?

E.g. have a task.json with the following shell command;

ssh -L50000:ipaddr_private:50000 root@ipaddr_jumphost 'gdbserver :50000 /usr/bin/program'

And the then launch.json for native gdb that has preLaunchTask to that?

GitMensch commented 1 year ago

A local re-routing, then connecting via that port sounds like an option - please test that and report back. Note: not sure what happens if you launch that shortly after another, I guess on the second time the prelaunch task would fail (because there is already a tunnel open) - in this case just have a separate task configured and run it manually when the connection fails.

infn-ke commented 1 year ago

From the gdbserver manual it says

The stdio connection is useful when starting gdbserver with ssh:

(gdb) target remote | ssh -T hostname gdbserver - hello

So tried to to use a launch task to do that and a the preLaunchTask to setup the ssh tunnel. But not sure how to get the syntax right in json file.

infn-ke commented 1 year ago

I tried "request": "launch" and then autorun

"autorun": [
    "target remote | sshpass -p root ssh -x -T root@remote_ip gdbserver - --attach pid",
],

but the vsode sends run, but I want it to send continue

Error message

Could not run/continue: The "remote" target does not support "run".  Try "help target" or "continue". (from exec-run --start)