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 生效。

参考

  1. Missing auto-load script in gdb #33159
  2. cmd/link: windows executable have no .debug_gdb_scripts section #20218
  3. 23.2.2.6 Selecting Pretty-Printers
  4. 23.2.2.7 Writing a Pretty-Printer
  5. Making life prettier with gdb PrettyPrinting API

Comments