使用GDB打印C++类对象

7

在调试C++应用程序时,是否有一些“默认函数”可以像字符串一样打印对象到GDB上?例如:toString();

还是我的类必须实现类似的功能?


这可能是你能得到的最接近的答案了。 https://dev59.com/XHI_5IYBdhLWcg3wDOhC - AlexLordThorsen
你有检查过这个吗?http://sourceware.org/gdb/wiki/STLSupport - 111111
你必须实现它。通常你可以在调试器中深入成员并查看你要找的内容。 - WhozCraig
1
最好的做法是为GDB编写一个Python漂亮打印机,以便在打印自己的类型时使用。链接 - Jonathan Wakely
4个回答

3
你总是可以使用print命令打印std::string(或其他任何内容)。然而,苦于C++模板容器内部可能不是令人愉快的事情。在最近的工具链版本中(GDB + Python + Pretty Printers通常作为大多数用户友好的Linux发行版开发包的一部分安装在一起),这些被自动识别并打印(漂亮!)。例如:
$ cat test.cpp 
#include <string>
#include <iostream>

int main()
{
    std::string s = "Hello, World!";
    std::cout << s << std::endl;
}

$ g++ -Wall -ggdb -o test ./test.cpp 
$ gdb ./test 

(gdb) break main
Breakpoint 1 at 0x400ae5: file ./test.cpp, line 6.
(gdb) run
Starting program: /tmp/test 

Breakpoint 1, main () at ./test.cpp:6
6       std::string s = "Hello, World!";
Missing separate debuginfos, use: debuginfo-install glibc-2.16-28.fc18.x86_64 libgcc-4.7.2-8.fc18.x86_64 libstdc++-4.7.2-8.fc18.x86_64
(gdb) next
7       std::cout << s << std::endl;
(gdb) p s
$1 = "Hello, World!"
(gdb) 

正如 @111111 指出的那样,请查看 http://sourceware.org/gdb/wiki/STLSupport 以获取有关如何自行安装此内容的说明。

2
最近的GDB并不足够,该输出是由最近版本的GCC中包含的漂亮打印机完成的,使用了最近版本的GDB中嵌入的Python解释器。 - Jonathan Wakely
@JonathanWakely:正确。可能更适合说工具链而不是gdb……这些东西通常会随着大多数“用户友好”的发行版的dev包默认安装。 - user405725

2
您可以在调试会话期间从标准库或自己的数据类型中 调用任何成员函数。这有时是在 gdb 中输出对象状态的最简单方法。对于 std::string,您可以调用它的 c_str() 成员函数,该函数返回 const char*
(gdb) p str.c_str()
$1 = "Hello, World!"

尽管这只适用于调试实时进程,而不适用于核心转储调试。

1

gdb内置print命令,可以在gdb上调用任何变量或表达式来查看其值。您应该查看gdb文档以获取详细信息。您可以在这里找到完整的手册,这里可以找到一个不错的简介指南。


1

定义operator<<并从GDB中调用它

C++中Java的toString的等效方法?在评论中提到,operator<<是在类上定义to string方法最常见的方式。

这可能是最明智的方法,因为生成的字符串方法本身将成为代码库的一部分,因此:

  • 它不太可能停止编译(我们希望如此!)
  • 它可以在没有任何GDB设置的情况下立即使用
  • 在需要时可以从C++中调用它

不幸的是,我还没有找到完全合理的调用operator<<的方法,真是一团糟: 在gdb中调用 operator<<

这在我的hello world测试中起作用:

(gdb) call (void)operator<<(std::cerr, my_class)
MyClass: i = 0(gdb)

结尾没有换行符,但我可以接受这样。

main.cpp

#include <iostream>

struct MyClass {
    int i;
    MyClass() { i = 0; }
};

std::ostream& operator<<(std::ostream &oss, const MyClass &my_class) {
    return oss << "MyClass: i = " << my_class.i;
}

int main() {
    MyClass my_class;
    std::cout << my_class << std::endl;
}

编译使用:

g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp

在GDB 8.1.0和Ubuntu 18.04中测试通过。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接