Skip to content

Instantly share code, notes, and snippets.

@JADC362
Last active April 10, 2024 23:18
Show Gist options
  • Star 60 You must be signed in to star a gist
  • Fork 18 You must be signed in to fork a gist
  • Save JADC362/a4425c2d05cdaadaaa71b697b674425f to your computer and use it in GitHub Desktop.
Save JADC362/a4425c2d05cdaadaaa71b697b674425f to your computer and use it in GitHub Desktop.
Debug ROS2 C++ node on VSCode (Ubuntu)

Debug ROS2 C++ node on VSCode (Ubuntu)

Description

This is a small tutorial on how to debug a ROS2 C++ node usign VSCode.

Requeriments

This implementation was done using:

Debug

Once you have your C++ code correctly implemented (at least compile), the First thing to do is to compile the package exporting the symbols (allow the breakpoints where you want to stop the code):

 - cd ros_ws
 - colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo
 - source install/setup.bash

Second, we have to launch the GDB Server for debbuging the CPP Code. Here, we will use a localhost:port for creating the server. Choose any free port that you want.

ros2 run --prefix 'gdbserver localhost:3000' package_name executable_name

Third, we have to create a launch.json on VSCode. In other words, we will create a custom debugging configuration. In our case, create a GDB client and connect to the server.

1) Open VSCode on your workspace.
2) Go to your side bar, 'Run and Debug' section.
3) Add a new configuration (Select C++ enviroment or any other)
4) On your launch.json file, put the following information

Launch.json file:

    {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "C++ Debugger",
                "request": "launch",
                "type": "cppdbg",
                "miDebuggerServerAddress": "localhost:3000",
                "cwd": "/",
                "program": "[build-path-executable]"
            }
        ]
    }
  • name - Custom name of your debugger configuration
  • request - In this case we want to launch the client
  • type - cppdbg for c++ debugging
  • miDebuggerServerAddress - path_server:port
  • cwd - Where to find all the required files. We use root because ROS, the package, and other required files are distributed along the entire PC.
  • program - Change [build-path-executable] by your executable build file. You can find this path on the console when you launch the server.

Lastly, use the VSCode buttons and panels option to debug correctly your code.

This implementation was found by Alejandro Duarte and Jeison Garcia.

@sandman
Copy link

sandman commented Oct 25, 2021

Great example! How can this be extended for the case where a launch file is used?

@iftahnaf
Copy link

Thanks, it works!
We added the colcon build and the server launch commands to the tasks.json and made a pre-launch task on the launch.json, so it all starts automatically after rebuilding the node.

@ZhenshengLee
Copy link

@iftahnaf add a prelaunch task is great
But when there is no source /opt/ros/galactic/setup.bash in .bashrc, you need to source manually before ros2 run in task of vscode.
This cannot be done to source in the task of vscode. What's your opinion?

@iftahnaf
Copy link

iftahnaf commented Mar 15, 2022

Hi @ZhenshengLee, I am sourcing the setup.bash in the tasks.json like this:

        "label": "debug_server",
        "command": "source /opt/ros/foxy/setup.bash && colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Debug 
        &&source /<path-to-local-ws>/local_setup.bash && ros2 run --prefix 'gdbserver localhost:3000' cpp_publisher talker", 
        "type": "shell",
        "presentation": {
            "echo": true,
            "reveal": "always",
            "focus": false,
            "panel": "shared",
            "showReuseMessage": true,
            "clear": false

@ZhenshengLee
Copy link

@iftahnaf thank you!

But I found that the prelaunch task will be waiting for Listening on port 8009 and the launch task will be blocked by the prelaunch task

see this https://github.com/ZhenshengLee/ros2_mcu/blob/a1aee40a03f9159629829928792a996ed01d2810/.vscode/launch.json#L19

@iftahnaf
Copy link

Hi @ZhenshengLee,

After the prelaunch and launch tasks, I run the node directly from the VSC with the run script option, then its stops at breakpoints and I can debug.

It doesn't work for you?

@sea-bass
Copy link

sea-bass commented Oct 25, 2022

Great example! How can this be extended for the case where a launch file is used?

If you're using a ROS2 Python launch file, you can add a prefix as follows. I also tend to print everything out with the output and emulate_tty options.

    demo_node = Node(
        package="my_package",
        executable="my_executable",
        name="my_node",
        namespace="my_namespace",
        prefix=["gdbserver localhost:3000"],
        output="screen",
        emulate_tty=True
    )

@AchmadFathoni
Copy link

How to gracefully exit the gdbserver within ros2 run? I must close the terminal manually every time.

@aserbremen
Copy link

Has anyone made this run under ROS2 humble? When trying to run ROS2 executable with ros2 run --prefix 'gdbserver localhost:3000' package_name executable_name I get the following error FileNotFoundError: [Errno 2] No such file or directory: 'gdbserver'

@sea-bass
Copy link

Has anyone made this run under ROS2 humble? When trying to run ROS2 executable with ros2 run --prefix 'gdbserver localhost:3000' package_name executable_name I get the following error FileNotFoundError: [Errno 2] No such file or directory: 'gdbserver'

I think this means you need to apt install gdbserver in your environment first...

@do335
Copy link

do335 commented Sep 28, 2023

helps a lot,thanks

@felixf4xu
Copy link

Great example! How can this be extended for the case where a launch file is used?

Same:

ros2 launch gnss_poser gnss_poser.launch.xml --launch-prefix "gdbserver localhost:3000"

@yfanda
Copy link

yfanda commented Mar 15, 2024

Hi, has anyone made a debug configuration of 2 or more nodes(e.g. A_node started and publishes a a.msg, B_node subscirbes it and publishes another b.msg)? what should I do with launch.json to make it work?

@JADC362
Copy link
Author

JADC362 commented Mar 18, 2024

@yfanda I don't think you can, it's like trying to debug two programs in the same vscode window. I guess you will have to open another VSCode window and use different launch.json files for every program (node). Theoretically, You could create a single launch.json file and pass as argument the executable path, and call on each window the program that you desire.

@yfanda
Copy link

yfanda commented Mar 19, 2024

@yfanda I don't think you can, it's like trying to debug two programs in the same vscode window. I guess you will have to open another VSCode window and use different launch.json files for every program (node). Theoretically, You could create a single launch.json file and pass as argument the executable path, and call on each window the program that you desire.

hey, thanks for reply. I built a launch.py in ros2, which just simply define the 2 nodes, and define it as the target in launch.json, as showed below:
"version": "0.2.0", "configurations": [ { "name": "ROS: Launch", "request": "launch", "target": "/home/evan/UAV_ws/install/uav_launch/share/uav_launch/launch/uav_launch.py", "launch": [ "rviz", "gz", "gzclient", "gzserver" ], "type": "ros" } ]
To build the ros2 workspace I used this command : colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Debug.
After I clicked the debugging button in vscode, it could run and stop at the breakpoints I set before. But somehow the program cannot continue after 3 or 4 breakpoints.

@moschmdt
Copy link

have a look at the VS Code ROS extension and the video tutorials provided. They should help you out quite a lot and debugging both nodes should be no problem either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment