ros2_controllers
ros2_controllers copied to clipboard
Using GDB with ROS2 Controllers
Hi All!
I am working on developing custom controllers using Controller Interface and am currently looking for a way to attach gdb with the ros2 controllers in order to be able to debug. I have used gdb before with ROS2 nodes, However, in the case of ros2 controllers, the controllers are created as plugin and are initialized through spawner. Hence, I am not really sure how to achieve this. Any suggestions is appreciate.
@bmagyar @christophfroehlich
Thanks!
I always used it just like with all nodes started via ros2 launch:
In the entry where you create the Node for the controller manager just add:
prefix=['xterm -e gdb -ex run --args']
and make sure you have xterm installed.
The controllers are loaded as plugins into the controller manager process.
Hi @firesurfer ! You are right that this works for all other ROS2 nodes but this does not work with ROS2 Controller plugins as a spawner node is used to load them from my understanding and spawner is written in python.
Yes but the spawner just tells the node in which the controller manager runs what to load. So you want to attach the debugger (in your preferred way) to the controller manager.
@firesurfer could you maybe add a simple tutorial for our docs? You can put a file here and add it to index.rst Thanks!
Thanks! @firesurfer I have tried the approach you mentioned as well as attaching gdb directly to the process after launching the nodes
The current problem I have is that I can attach the gdb to the controller manager and I can see the xterm. But how do I specify that I would like to put breakpoints on for example line number 55 of some custom controller plugin, where multiple controller can be loaded at the same time.
@christophfroehlich Yes I agree, a documentation on it will be great.
Thanks!
There is actually quite a lot of information on how to debug ros(2) nodes run from a launch. ros2control is only special that you need to attach to the controller_manager for debugging a plugin.
It basically boils down to two variants:
a) tell the launch file to run the node with gdb attached (we need to this in an separate terminal because the way ros2 launch works) - this is what I presented. In this case you need to learn how to use the cli interface of gdb
b) tell the launch file to run the node with a gdbserver instance attached prefix=["gdbserver localhost:3000"]
You can then attach to that gdbserver session whatever way fits you best. This can either be the command line, vscode, or whatever you prefer.
This link summarize it quite nice: https://juraph.com/miscellaneous/ros2_and_gdb/
Also remember two things: 1. You need to build with debug information 2. In optimized builds breakpoints might not break at the point you want to break
The challenge you will be facing with ros2control is that you want to debug a plugin. The plugin needs to be loaded before you can set breakpoints: See https://stackoverflow.com/questions/10919832/how-to-use-gdb-to-debug-a-plugin
Also a note from my experience: For applications that have a realtime loop I barely / never use breakpoints as this can/will mess up a lot of things. I use gdb usually for debugging crashes (e.g. segfaults) where the backtrace can be really useful. Otherwise cout (even if often looked down upon) debugging or adding additional debug state interfaces might be the right way to go.
@christophfroehlich I see this is quite a lot of information. Perhaps you are right about some documentation. I can add this
@aadi-mishra please take a look at the added documentation and tell us if it solves your problem. If so please close the issue.
@firesurfer Documentation Looks great. Thanks a lot! I am closing this issue now.