简体   繁体   English

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

[英]examining memory in gdb pretty-printer

I'm trying to figure out how GDB pretty printing works in order to create some pretty printers that will display data structures in a more compact, readable form, but the documentation seems pretty thin. 我试图找出GDB漂亮打印的工作原理,以便创建一些漂亮的打印机,以更紧凑,可读的形式显示数据结构,但文档似乎很薄。 As a starting exercise, I tried to create a pretty printer for a sockaddr_in -- instead of printing umpteen different union variations in an unreadable form, just print it in normal dotted notation. 作为一个开始练习,我试图为sockaddr_in创建一个漂亮的打印机 - 而不是以不可读的形式打印不同的联合变体,只需用正常的点缀表示法打印它。

I put the following in my .gdbinit file: 我在我的.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

This seems to load ok, but when I try to print a sockaddr_in, I get an opaque error message: 这似乎加载好,但是当我尝试打印sockaddr_in时,我收到一条不透明的错误消息:

(gdb) p srcaddr
Python Exception <type 'exceptions.RuntimeError'> Value is not callable (not TYPE_CODE_FUNC).: 
$2 = 
(gdb)

Any ideas as to what is going wrong? 什么是错的任何想法?

Anyone have any good pointers to documentation about writing/using/debugging gdb pretty printing functions? 任何人都有关于编写/使用/调试gdb漂亮打印功能的文档的任何好的指针? Much of the above is cribbed from examples found around the web, as that appears to be the only 'documentation' available. 以上大部分内容都来自网络上的例子,因为这似乎是唯一可用的“文档”。

edit 编辑

changing the addr/port stuff to 将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())

fixes that exception, but leads to 修复了这个异常,但导致了

(gdb) p src
Python Exception <class 'gdb.error'> Argument to arithmetic operation not a number or boolean.: 
$1 = 

..still no line number info to indicate where the problem is. ..still没有行号信息,以指示问题所在。

edit 编辑

after lots of random twiddling of the code, I figured out that I need: 经过大量随机的代码编写后,我发现我需要:

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 is a property, not a function. Value.address是属性,而不是函数。 So when you write ".address()", you are telling gdb to try to make an inferior function call. 所以当你写“.address()”时,你告诉gdb尝试做一个较差的函数调用。 Instead write ".address". 而是写“.address”。

Please file bug reports in gdb bugzilla for any documentation issues. 请在gdb bugzilla中提交bug报告以解决任何文档问题。 The current documentation is written in a "reference" style, but adding examples is probably worth doing. 当前文档以“引用”样式编写,但添加示例可能值得一试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM