When Debug Symbols Get Large
randomascii.wordpress.com
randomascii.wordpress.com
The backtrace -- as in, just the output from running `bt` in GDB -- was over a thousand wrapped lines long. There were ~5 stack frames that took up over a hundred lines of console each to print just the function name. That product's debug builds recently hit the 2GB line, which is enough that old versions of binutils complain.
I don't know what the solution is. There's some really neat stuff you can do with template metaprogramming, and in stripped release builds it compiles down extremely tiny. Plus the code is very clean to read. But it does feel like there isn't any kind of central vision for the C++ debugging experience, and bad interactions between highly-complex modern C++ libraries, the compiler, and the debugger are probably only going to get worse unless somebody (the ISO committee? vendors? every single library author individually?) thinks really hard about debugging support.
You don't even need template metaprogramming to get a horrible experience. Just imagine using std::transform and wanting to step. You obviously want to step through your lambda that you pass it. You don't want to step through the over 9000 lines of whatever the fuck libstdc++ is doing to make std::transform work. In most cases you can't even set a breakpoint in your lambda because breakpoints are set by line number, so you'll hit the break in the transform. Leaving you needing to reformat your source code and recompile just to set a reasonable breakpoint.
This particular problem could be solved if the debugger let you say "skip through some namespace (like std) but stop if it calls something else" but c++ debugging has all sorts of nonsense like this. Honestly I've just stopped using debuggers with c++ over a decade ago. It's just not worth fighting with it.
I think the people that need to think about debugging ergonomics isn't the standard committee or the library authors. It's the authors of whoever is writing the next debugger. Gdb is great for C but it really doesn't map to C++ well at all.
It stops you stepping into namespaces you don't want to see but doesn't do anything when you step out into them.
It also doesn't handle when code you don't want to see calls back into code you do - and, yes, I've recommended formatting lambdas to allow breakpoints before.
I believe DWARF does support columnar information these days so it actually should be possible to solve the one line lambda given code in GDB.
For looking at any data in C++ it's also very important to have GDB's pretty printers set up (and, likely, write some of your own).
https://sourceware.org/gdb/onlinedocs/gdb/Pretty_002dPrinter...
https://undo.io/resources/gdb-watchpoint/here-quick-way-pret... (this one is from my boss)
At what point is it better to just rename everything to use the sha256 of the "real" name? It's obviously only for machine use anyways, so it's not like one more layer of indirection would hurt.
It was handy to see the outer couple of layers of template expansion, though, so I could know at least which library it came from. I’d be very interested in some way to adjust the displayed format to be different from the “real” type name (which is of course different from the machine-readable mangled name). It might be better to put that functionality in the debugging tool.
Debug symbols in general tend to be very big. You need to be able to map each instruction in the binary to a line of code. You can expect a compiler to break each line of code into several instructions, and you can also expect that the instructions are out of order and interleaved with neighboring lines of code. So each instruction will need its own unique entry.
> I am willing to bet that the executable and the source code combined together would take less space,
~ $ ll -h /var/cache/distfiles/chromium-110.0.5481.177.tar.xz
-rw-rw-r-- 1 portage portage 1.6G Feb 22 11:02 /var/cache/distfiles/chromium-110.0.5481.177.tar.xz
~ $ tar -xaf /var/cache/distfiles/chromium-110.0.5481.177.tar.xz
~ $ du -sh chromium-110.0.5481.177/
13G chromium-110.0.5481.177/https://commondatastorage.googleapis.com/chromium-browser-of...
The compiled binary is much smaller:
~ $ du -h /usr/lib64/chromium-browser
16K /usr/lib64/chromium-browser/MEIPreload
360K /usr/lib64/chromium-browser/locales
383M /usr/lib64/chromium-browserA clean checkout of chromium is 5 GB (excluding the .git folder) by itself, the symbols will of course be larger.
char demangled[256]; // Big enough for sane demangled symbols.
Turns out the longest symbol name in the Chrome binary is 32k characters long... and some of the tests have even longer ones (the longest one I found was 98k characters).