0. 我的环境
CentOS Linux release 7.6.1810 (Core)
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-114.el7
1. 让gdb找到你的脚本
a) gdb可以根据载入的“可执行程序”或者“动态库”,自动加载相应的python脚本
默认目录 /usr/share/gdb/auto-load/
例如:安装glib-2.0会自动安装/usr/share/gdb/auto-load/usr/lib64/libglib-2.0.so.0.5600.1-gdb.py,那么当gdb载入/usr/lib64/libglib-2.0.so.0.5600.1时,就自动执行该脚本
b)~/.gdbinit
添加内容:add-auto-load-safe-path /path/allowed/to/load/python/scripts
同时,在需要调试的程序(例如:/home/user/a.out)所在目录,添加你自己的脚本(例如:/home/user/a.out-gdb.py)
2. 一个简单的Printer实现
简单的测试代码:
#include <string>
class Book {
public:
Book(int a, int b) :v1(new int(a)), v2(new int(b)) {}
int *v1 = nullptr;
int *v2 = nullptr;
};
int main(int argc, char **argv)
{
Book mybook(10, 20);
return 0;
}
程序位置(方案1):
/bin/test_gdb_printer
自动加载脚本位置(方案1):
/usr/share/gdb/auto-load/bin/test_gdb_printer-gdb.py
程序位置(方案2):
/home/code/a.out
自动加载脚本位置(方案2):
/home/code/a.out-gdb.py
~/.gdbinit(方案2):
add-auto-load-safe-path /home/code/
自动加载脚本内容:
import sys
import gdb
# Update module path.
dir_ = '/home/code'
if not dir_ in sys.path:
sys.path.insert(0, dir_)
from test_gdb_printer_gdb import register
register (gdb.current_objfile ())
/home/code/test_gdb_printer_gdb.py
import gdb
class BookPrinter(object):
def __init__(self, val):
self.val = val
def to_string(self):
return "{v1=%d, v2=%d}" % (self.val["v1"].dereference(), self.val["v2"].dereference())
def pretty_printer_lookup (val):
type = val.type.unqualified()
t = str(type)
if t == "Book":
return BookPrinter(val)
return None
def register (obj):
if obj == None:
obj = gdb
obj.pretty_printers.append(pretty_printer_lookup)
使用:
gdb a.out,在return 处断点;
执行gdb命令: print mybook
(gdb) p mybook
$1 = {v1=10, v2=20}
3. 参考资料
https://sourceware.org/gdb/onlinedocs/gdb/Writing-a-Pretty_002dPrinter.html
https://www-zeuthen.desy.de/unix/unixguide/infohtml/gdb/Auto_002dloading.html