You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

两种GDB漂亮打印机注册方式输出差异原因及冗余消除方法

GDB两种漂亮打印机注册方式的输出差异问题

C++测试代码

struct number
{
    int n;
};

int main()
{
    number n{5};
    const number & ref = n;
}

两种GDB漂亮打印机实现

Printer1(旧注册方式)

class Printer:
    def __init__(self, val):
        self.val = val

    def to_string(self):
        return str(self.val["n"])

def matcher(val):
    lookup_tag = val.type.tag
    if lookup_tag is None:
        return None

    if lookup_tag == "number":
        return Printer(val)

gdb.pretty_printers.append(matcher)

Printer2(使用RegexpCollectionPrettyPrinter的新注册方式)

class Printer:
    def __init__(self, val):
        self.val = val

    def to_string(self):
        return str(self.val["n"])

def build_pretty_printer():
    pp = gdb.printing.RegexpCollectionPrettyPrinter("num")
    pp.add_printer("num", "^number$", Printer)
    return pp

gdb.printing.register_pretty_printer(None, build_pretty_printer())

输出差异

使用Printer1打印ref时,GDB输出:

$1 = (const number &) @0x7fffffffe0b8: 5

使用Printer2打印ref时,GDB输出:

$1 = 5

问题

两种方式的Printer实现完全一致,仅注册方式不同。请问为何两种注册方式会导致输出差异?Printer1为何会打印(const number &) @0x7fffffffe0b8?如何消除该冗余内容?


解答

差异原因

  1. 旧注册方式的局限性:直接将matcher追加到gdb.pretty_printers的方式,只会匹配传入的原始值类型。当打印引用类型const number &时,GDB认为当前值的类型是引用而非底层的number结构体,因此会先输出引用的类型和内存地址,再调用打印机打印引用指向的对象内容,最终呈现带冗余信息的输出。
  2. 新注册方式的自动处理:RegexpCollectionPrettyPrinter是GDB官方封装的工具,内部会自动处理引用、指针等包装类型——它会先自动解引用,提取到底层的number对象再应用打印机,因此不会输出引用的额外信息。

消除Printer1的冗余内容

修改matcher函数,提前处理引用类型,手动解引用得到底层对象:

class Printer:
    def __init__(self, val):
        self.val = val

    def to_string(self):
        return str(self.val["n"])

def matcher(val):
    # 处理引用类型,手动解引用
    val_type = val.type
    if val_type.code == gdb.TYPE_CODE_REF:
        val = val.referenced_value()
        val_type = val.type
    # 可选:添加指针类型处理,支持指针打印
    elif val_type.code == gdb.TYPE_CODE_PTR:
        val = val.dereference()
        val_type = val.type
    
    lookup_tag = val_type.tag
    if lookup_tag is None:
        return None

    if lookup_tag == "number":
        return Printer(val)

gdb.pretty_printers.append(matcher)

修改后,打印ref时会和Printer2输出一致,仅显示5。


内容的提问来源于stack exchange,提问作者user13840624

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 22:59:57