GDB printers
GDB Printers¶
这样的输出实在太丑了,干扰调试。
$1 = std::vector of length 3, capacity 3 = {1, 2, 3}
山重水复¶
找到了STL Support Tools, 却不知道什么哪里加载了 libstdcxx.v6.printers(/usr/share/gcc-8/python/libstdcxx/v6/printers.py)这个模块,运行前:
(gdb) python >import sys >print(sys.path) >end ['/usr/share/gdb/python', '/usr/lib/python36.zip', '/usr/lib/python3.6', '/usr/lib/python3.6/lib-dynload', '/home/ubuntu/.local/lib/python3.6/site-packages', '/usr/local/lib/python3.6/dist-packages', '/usr/lib/python3/dist-packages']
执行 run 命令运行后:
(gdb) python >import sys >print(sys.path) >end ['/usr/lib/x86_64-linux-gnu/../../share/gcc-8/python', '/usr/share/gdb/python', '/usr/lib/python36.zip', '/usr/lib/python3.6', '/usr/lib/python3.6/lib-dynload', '/home/ubuntu/.local/lib/python3.6/site-packages', '/usr/local/lib/python3.6/dist-packages', '/usr/lib/python3/dist-packages']
查找 .debug_gdb_scripts 段时:
$ readelf -x.debug_gdb_scripts a.out readelf: Warning: Section '.debug_gdb_scripts' was not dumped because it does not exist! $ objdump -sj.debug_gdb_scripts /usr/lib/x86_64-linux-gnu/libstdc++.so.6 /usr/lib/x86_64-linux-gnu/libstdc++.so.6: file format elf64-x86-64 objdump: section '.debug_gdb_scripts' mentioned in a -j option, but not found in any input file
使用g++ -static -g a.out a.cpp
的输出调试发现就出现了更粗糙的输出:
(gdb) print out $1 = {<std::_Vector_base<int, std::allocator<int> >> = { _M_impl = {<std::allocator<int>> = {<__gnu_cxx::new_allocator<int>> = {<No data fields>}, <No data fields>}, _M_start = 0x6ef730, _M_finish = 0x6ef73c, _M_end_of_storage = 0x6ef73c}}, <No data fields>}
那就可以确定肯定时动态库造成的自动加载。最后想起之前调试 Python 代码时碰见的 python-gdb.py。
柳暗花明¶
Debugging with GDB: Python Auto-loading When a new object file is read (for example, due to the file command, or because the inferior has loaded a shared library), GDB will look for Python support scripts in several ways: objfile-gdb.py and .debug_gdb_scripts section.
$ dpkg -L libstdc++6|grep -F libstdc++.so.6.0.25-gdb.py
/usr/share/gdb/auto-load/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25-gdb.py
果然如此,这个文件里有调用 sys.path.insert,然后register_libstdcxx_printers(gdb.current_objfile())
,最后 StdVectorPrinter 生效。
参考¶
- Missing auto-load script in gdb #33159
- cmd/link: windows executable have no .debug_gdb_scripts section #20218
- 23.2.2.6 Selecting Pretty-Printers
- 23.2.2.7 Writing a Pretty-Printer
- Making life prettier with gdb PrettyPrinting API