1

I'm using Linux. I have a game which uses a GDNative extension that I'm writing in Rust, but the extension is called GDScript. I'd like to be able to launch the game from Visual Studio code and set break-points in both Rust and GDScript from the same editor.

One problem is that the Godot executable is run multiple times, once for the VSCode Godot plugin, and again to run my program.

I tried attaching to a running process with LLDB. Unfortunately the Compound Launch with the GDScript debugger and the LLDB debugger fails to launch. This is because LLDB needs the PID for godot, but the Compound Launch refuses to start the Godot executable until LLDB has all its parameters--including the PID of the process to attach to. It's possible to launch both debuggers separately, but I'd like to launch them together.

My launch.json:

{
    "name": "GDScript Debug",
    "type": "godot",
    "request": "launch",
    "project": "${workspaceFolder}",
    "port": 6007,
    "address": "127.0.0.1",
    "launch_game_instance": true,
    "launch_scene": false
},
{
    "name": "Rust Only Debug",
    "type": "lldb",
    "request": "launch",
    "program": "/home/nathan/bin/godot",
    "args": ["--position","3840,144", "res://Main.tscn"],
    "cwd": "${workspaceFolder}"
}

It's possible to debug using the godot editor and then attach LLDB to the running process. By using the Tasks Shell Input Extension, I can find the correct PID using pgrep.

"configurations": [
    {
        "name": "Attach Rust Debug",
        "type": "lldb",
        "request": "attach",
        "pid": "${input:GodotNotEditingPID}"
    }
],
"inputs": [
    {
      "id": "GodotNotEditingPID",
      "type": "command",
      "command": "shellCommand.execute",
      "args": {
        "command": "pgrep --full godot.\\*remote-debug",
        "description": "Ignore the editor, select the program we're debugging",
        "useFirstResult": true,
      }
    }
],

How can I Start Both GDScript debugging and GDNative debugging at the same time from VS Code?

1 Answer 1

1

Your program can also call Visual Studio Code with the debug information to ask LLDB to connect as described here. This was tested with GDScript/Rust GDNative on Linux, but should work for GDExtensions & C++ or C# too. Option 1 should work on any Windows, MacOS or Linux. Option 2 is more elegant, but it may only work with Linux & MacOS.

Option 1

Add a callback from your GDNative binary

Rust:

#[cfg(debug_assertions)]
{
    let url = format!("vscode://vadimcn.vscode-lldb/launch/config?{{'request':'attach','pid':{}}}", std::process::id());
    std::process::Command::new("code").arg("--open-url").arg(url).output().unwrap();
    std::thread::sleep_ms(1000); // Wait for debugger to attach
}

C:

char command[256];
snprintf(command, sizeof(command), "code --open-url \"vscode://vadimcn.vscode-lldb/launch/config?{'request':'attach','pid':%d}\"", getpid());
system(command);
sleep(1); // Wait for debugger to attach

Option 2

For Linux or MacOS, use a preLaunchTask to launch a background task that uses pgrep to find the correct godot process and call VS Code. Although it's called pre-launch, it actually sleeps a couple seconds to wait for Godot to launch and get its Process ID.

Add this to launch.json:

    // This waits a second and calls VS code to attach lldb
    "preLaunchTask": "Attach LLDB Later"

And then add this to tasks.json:

{
    "label": "Attach LLDB Later",
    "type": "shell",
    "command": "/bin/bash",
    // Called from a preLaunchTask.  First wait for it to start up.
    // Then call VS code and tell it to attach with the LLDB debugger.
    "args": ["-c", "echo Waiting for launch...;sleep 2; code --open-url \"vscode://vadimcn.vscode-lldb/launch/config?{\\\"request\\\":\\\"attach\\\",\\\"pid\\\":$(pgrep --full --newest godot.\\*remote-debug)}\";echo LLDB attached."],
    "isBackground": true,
    // All this is needed so VSCode doesn't complain about the background task.
    "problemMatcher": [
        {
        "pattern": [
            {
            "regexp": ".",
            "file": 1,
            "location": 2,
            "message": 3
            }
        ],
        "background": {
            "activeOnStart": true,
            "beginsPattern": ".",
            "endsPattern": ".",
        }
        }
    ]
},

The "pgrep --full --newest godot.\*remote-debug" will search for the correct godot process. The VSCode Godot Plugin runs the editor too, but this doesn't have "remote-debug" in the full command line. By making this a background task, it solves the catch-22. The problem matcher looks for any output, even if it just says it's waiting.

Now I can set a breakpoint in both GDScript and the GDNative plugin in the same VSCode editor, and both breakpoints work.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.