在gdb漂亮的打印机中检查内存

时间:2013-07-03 18:54:56

标签: python gdb pretty-print

我正在试图弄清楚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 / port内容更改为

 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

1 个答案:

答案 0 :(得分:4)

Value.address是属性,而不是函数。所以当你写“.address()”时,你告诉gdb尝试做一个较差的函数调用。而是写“.address”。

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

相关问题