corrade
corrade copied to clipboard
Add GDB pretty-printers for some types.
As mentioned on Gitter, here's the PR adding adding GDB pretty-printers
Most types in Containers
, as well as most Utility::Configuration*
types (except values, since the default printing for them is adequate), are supported.
For multi-dimensional StridedArrayView
, since I couldn't manage to get nested printing working, flattened printing is used instead.
The only Containers
type to not be supported is ScopeGuard
, because type erasure makes it hard to pretty-print its contents.
Note: because the gdb.Type.template_argument()
method chokes on non-type arguments (such as the size used by StaticArray(View)
, or StridedArrayView
's dimensions) despite this bug supposedly being fixed in GDB 7.2, I had to rely on string manipulation to extract those arguments.
Codecov Report
Merging #147 (5990edb) into master (38e4677) will not change coverage. The diff coverage is
n/a
.
@@ Coverage Diff @@
## master #147 +/- ##
=======================================
Coverage 97.92% 97.92%
=======================================
Files 132 132
Lines 10750 10750
=======================================
Hits 10527 10527
Misses 223 223
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.
Thank you! I looked over the code and everything seems fine, even the coding style is exactly as I'd do it myself, haha. I don't really use gdb myself so I can't prove it actually works, but I think I can trust you after all these years :)
Two questions before I merge:
- What should I put into the docs so people know how to use this?
- I was wondering if it would make sense to restrict the installation only if GCC/Clang is used (i.e., don't install if MSVC is used). But then there's a case of MinGW, and clang-cl, and maybe GDB can work with PDB files, who knows, and I'm not sure if all that extra logic is worth the bother, so probably just easiest to install always?
flattened printing is used instead.
That's fine. It can be always added later if someone figures out how.
ScopeGuard
This is fine as well, I don't see this type being too important. Besides that, the type usually just takes a value/variable that's stored somewhere else already, so the user can print the other one instead.
chokes on non-type arguments
Ah, sigh. So I suppose the Magnum math types all need the same workaround as well.
- What should I put into the docs so people know how to use this?
Oh, boy... :D
To be honest, once again, there's no easy way of loading pretty-printers.
It's possible to do this:
- manually through GDB's commands
- by sourcing a GDB script file (there's a handy, well,
source
command for that) - by enabling auto-loading of scripts (GDB docs, JetBrains CLion docs).
- In the case of MSYS2/MinGW's GDB, the per-user
.gdbinit
file can be either in the MSYS2$HOME/.gdbinit
, or inC:\Users\<name>\.config\gdb\gdbinit
, depending on whether it's run in a MSYS2 shell or not. Non-MSYS2 GDB might use the latter too, but I currently don't have one of these to test with.
The scripts themselves tend to be a bit convoluted and a bit "WTF". Here's what GDB on MinGW-w64/MSYS2 does when loading the libstc++ pretty-printers (/mingw64/etc/gdbinit
), for example:
python
import sys
sys.path.insert(0, sys.path[0] + '/../../gcc-12.1.0/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end
Loading the Corrade pretty-printers might look like this (skipping the python
and end
commands for the sake of syntax highlighting:
import sys
sys.path.insert(0, '/path/to/share/') # not pointing to the debuggers subfolder here because it could conflict with the built-in gdb module
from corrade.debuggers.gdb import register_corrade_printers
register_corrade_printers(gdb.current_objfile())
Initialisation scripts for an "objfile" (aka a binary or dynamic library) can be directly a Python script, as per GDB's docs, in which case the python
and end
commands aren't needed.
It's also possible to register printers to a "progspace" (aka the entire inferior, including loaded libraries) using gdb.current_progspace()
, though I don't know if it actually makes a difference. Passing None
works too, and will register the pretty-printers globally, which may be unsuitable when dealing with multiple inferiors, as the printers could get registered multiple times.
That's all I could think of at the moment. If I missed anything that could be of use, don't hesitate to mention it.
- I was wondering if it would make sense to restrict the installation only if GCC/Clang is used (i.e., don't install if MSVC is used). But then there's a case of MinGW, and clang-cl, and maybe GDB can work with PDB files, who knows, and I'm not sure if all that extra logic is worth the bother, so probably just easiest to install always?
MinGW being pretty much GCC, I don't think this should be an issue.
In the case of Clang, it depends on whether GDB or LLDB is used to debug, and LLDB uses its own API according to the official docs, meaning the GDB scripts are useless in this case.
IIRC, clang-cl generates PDB debug info, meaning only VS (and LLDB, thanks to MS being more open about the format) can be used.
GDB can't work with PDB files yet, but it's possible the option might come in the future, like with LLDB above.
Awesome, that's quite an exhaustive info. Will merge tomorrow or later this week, thank you!
Merged as 43d8fa0dae83e0542c919c5b90614c8215ee7865, finally. Sorry for the extreme delay and thanks!