2

データ構造をよりコンパクトで読みやすい形式で表示するきれいなプリンターを作成するために、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 プリティ印刷機能の作成/使用/デバッグに関するドキュメントへの適切なポインタを持っている人はいますか? 上記の多くは、Web で見つかった例から引用したものです。これは、利用可能な唯一の「ドキュメント」であるように思われます。

編集

アドレス/ポートのものをに変更する

 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
4

1 に答える 1