python - 检查 gdb pretty-print 中的内存

标签 python gdb pretty-print

我试图弄清楚 GDB pretty-print 是如何工作的,以便创建一些 pretty-print ,以更紧凑、可读的形式显示数据结构,但文档似乎很薄。作为开始练习,我尝试为 sockaddr_in 创建一个 pretty-print - 而不是以不可读的形式打印无数不同的联合变体,只需以正常的点符号打印它。

我将以下内容放入我的 .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 pretty-print 函数的文档吗?上面的大部分内容都是从网络上找到的示例中抄袭的,因为这似乎是唯一可用的“文档”。

编辑

将地址/端口内容更改为

 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

最佳答案

Value.address 是一个属性,而不是一个函数。因此,当您编写“.address()”时,您是在告诉 gdb 尝试进行次等函数调用。而是写“.address”。

请在 gdb bugzilla 中提交错误报告以了解任何文档问题。当前的文档是以“引用”风格编写的,但添加示例可能是值得的。

关于python - 检查 gdb pretty-print 中的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17456001/

相关文章:

python - Sublime Text Python 构建和打开终端需要很长时间

python - 如何替换 infs 以避免 PyTorch 中的 nan 梯度

python - 在 python 中转换 64 位 Windows 日期时间

c++ - 调试重启守护进程

json - 我如何使用 Go 漂亮地打印 JSON?

templates - Freemarker 在模板中打印日期

python - 如何在 python 中使用比较符号进行输入

c - 运行 'finish' 命令时 GDB 退出

GDB:远程加载共享库时出错

python - 将 print+format 推广为可变数量的输入