如何使用 gdb 制作一个可以漂亮地打印每个对象的 C++ 函数?

Posted

技术标签:

【中文标题】如何使用 gdb 制作一个可以漂亮地打印每个对象的 C++ 函数?【英文标题】:How can I make a C++ function that can pretty print every object, using gdb? 【发布时间】:2020-02-21 16:45:31 【问题描述】:

在 linux 中,如果使用 -g 选项编译程序,我可以使用 gdb 调试器打印每个对象。能不能写出类似的函数

template<typename T> ostream& to_stream(ostream& out, const T& obj);

用名称和类型序列化我的对象?

自然是借助 gdb 调用或系统调用等。

【问题讨论】:

我们需要更多细节。你想完成什么? 您是否正在寻找一些 C++ 的调试信息 API? 【参考方案1】:

如果你没有 gdb,你将无能为力。

magic_get 在某些有限的情况下有效。

对于其余部分,您通常必须手动指定字段名称,可能通过宏来使其更方便,但仍然是手动的。

visual c++ - Printing values of all fields in a C++ structure - Stack Overflow


如果您有 gdb(如,您可以保证程序将在 gdb 中运行)但是,(如问题中所述), 使用一种技术 c - Sending commands to gdb from the debugged program - Stack Overflow 我们有(您需要从该帖子中复制的 Python 代码在 gdb 中运行)

void gdb_run([[maybe_unused]] char const* str) 

template<class T> void gdb_pretty_print([[maybe_unused]] T const& arg)
    gdb_run("up\nprint arg");


struct Example
    int a;
    char b;
;

int main()
    gdb_pretty_print(Example1, '0');

如果您想将结果传递给 C++,您可以执行类似的操作

template<class T> void gdb_pretty_print([[maybe_unused]] T const& arg)
    char const* volatile result=nullptr;
    gdb_run("up\n"
            "python gdb.set_convenience_variable('result', gdb.execute('print arg', to_string=True))\n"
            "set result=$result");
    __builtin_printf("result = %s\n", result);

其实我不确定volatile 是否会这样做,或者用-O0 编译特定的。


或者,您可以尝试在gdb_pretty_print 本身内设置断点,但我尝试过非常困难。

class GdbPrettyPrint(gdb.Breakpoint):
    def __init__(self, function_name):
        super().__init__(function_name, internal=1)
        self.silent = True

    def stop(self):
        gdb.execute("print arg")
        return False

def set_breaks():
    for b in gdb.rbreak("^gdb_pretty_print<"):
        GdbPrettyPrint(b.location.split(":")[-1])
        b.delete()

不幸的是,您必须运行set_breaks() 函数。出于某种原因,单独rbreak 对我不起作用。

示例程序

template<class T> void gdb_pretty_print(T const& arg)
    (void) arg;


struct Example
    int a;
    char b;
;

int main()
    gdb_pretty_print(Example1, '0');

【讨论】:

【参考方案2】:

是的,你可以用 python Pretty Printing API 做到这一点。要开始漂亮的打印,您可以查看this question 和 Tom Tromey 的博客:http://tromey.com/blog/?p=524。

【讨论】:

(我没有投反对票,但是)我认为您误解了这个问题。它询问如何编写 C++ 函数(甚至在最近的编辑之前)

以上是关于如何使用 gdb 制作一个可以漂亮地打印每个对象的 C++ 函数?的主要内容,如果未能解决你的问题,请参考以下文章

带有 Qt 漂亮打印机的 gdb

是否可以生成一个伪类型,以便我可以伪造 gdb 漂亮的打印系统?

如何有效地漂亮打印 JSON 对象列表? [复制]

如何漂亮地打印嵌套字典?

如何使用 Go 漂亮地打印 JSON?

为 Qt5 配置 GDB python 漂亮打印机