我试图弄清楚 GDB 漂亮打印是如何工作的,以便创建一些漂亮的打印机,这些打印机将以更紧凑、更易读的形式显示数据结构,但文档似乎很薄。作为一个开始练习,我尝试为 sockaddr_in 创建一个漂亮的打印机——而不是以不可读的形式打印无数不同的联合变体,只需以正常的点分符号打印它。
我将以下内容放入我的.gdbinit
文件中:
python
class sockaddr_in_Printer(object):
"Print a sockaddr_in"
def __init__(self, val):
self.val = val
def to_string(self):
addr = self.val['sin_addr'].address().cast(gdb.lookup_type("unsigned char *"))
port = self.val['sin_port'].address().cast(gdb.lookup_type("unsigned char *"))
rv = "" + addr.dereference()
for x in range(0,3):
addr += 1
rv += "."
rv += addr.dereference()
pnum = port.dereference() * 256
port += 1
pnum += port.dereference()
rv += ":"
rv += pnum
return rv;
def find_pp(val):
if val.type.tag == 'sockaddr_in':
return sockaddr_in_Printer(val)
return None
gdb.pretty_printers.append(find_pp)
end
这似乎加载正常,但是当我尝试打印 sockaddr_in 时,我收到一条不透明的错误消息:
(gdb) p srcaddr
Python Exception <type 'exceptions.RuntimeError'> Value is not callable (not TYPE_CODE_FUNC).:
$2 =
(gdb)
关于出了什么问题的任何想法?
任何人都对有关编写/使用/调试 gdb 漂亮打印功能的文档有任何好的指导吗?以上大部分内容来自网络上的示例,因为这似乎是唯一可用的“文档”。
编辑
将地址/端口内容更改为
addr = self.val['sin_addr'].address.cast(gdb.lookup_type("unsigned char").pointer())
port = self.val['sin_port'].address.cast(gdb.lookup_type("unsigned char").pointer())
修复了该异常,但导致
(gdb) p src
Python Exception <class 'gdb.error'> Argument to arithmetic operation not a number or boolean.:
$1 =
..仍然没有行号信息来指示问题所在。
编辑
在对代码进行了大量随机旋转之后,我发现我需要:
python
class sockaddr_in_Printer(object):
"Print a sockaddr_in"
def __init__(self, val):
self.val = val
def to_string(self):
ptr_type = gdb.lookup_type("unsigned char").pointer()
addr = self.val['sin_addr'].address.cast(ptr_type)
port = self.val['sin_port'].address.cast(ptr_type)
rv = str(int(addr.dereference()))
for x in range(0,3):
addr += 1
rv += "."
rv += str(int(addr.dereference()))
pnum = port.dereference() * 256
port += 1
pnum += port.dereference()
rv += ":"
rv += str(pnum)
return rv;
def find_pp(val):
if val.type.tag == 'sockaddr_in':
return sockaddr_in_Printer(val)
return None
gdb.pretty_printers.append(find_pp)
end