2013-07-03 156 views
1

我想弄清楚GDB漂亮打印如何創建一些漂亮的打印機,將以更緊湊,可讀的形式顯示數據結構,但文檔看起來很薄。作爲一個開始練習,我試圖爲sockaddr_in創建一個漂亮的打印機 - 而不是以不可讀的形式打印許多不同的聯合變體,只是以正常的點綴符號打印它。檢查內存在GDB漂亮打印機

我把我的.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 = 

..still沒有行號信息以指示問題是。

編輯

大量代碼的隨機擺弄之後,我想通了,我需要:

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 

回答

4

Value.address是一個屬性,而不是功能。所以當你寫「.address()」時,你告訴gdb嘗試進行低級函數調用。而是寫下「.address」。

請在gdb bugzilla中爲任何文檔問題提交錯誤報告。當前的文檔是以「參考」風格編寫的,但添加示例可能是值得的。