用GDB打印c++类对象

Printing C++ class objects with GDB

本文关键字:对象 c++ 打印 GDB      更新时间:2023-10-16

当我们调试c++应用程序时,是否有一些"默认函数"来在GDB上打印像字符串一样的对象?例如:toString();

或者我的类必须实现类似的东西?

您总是可以使用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获取如何安装这个的说明。

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

(gdb) p str.c_str()
$1 = "Hello, World!"

gdb有一个内置的print命令,您可以在gdb中对任何变量或表达式调用该命令以查看其值。您应该查看gdb文档以了解详细信息。你可以在这里找到完整的手册,在这里可以找到一个像样的介绍指南

定义operator<<并从GDB调用

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

这可能是最合理的方法,因为结果字符串方法将是代码库本身的一部分,因此:

  • 它是更少停止编译(希望!)
  • 无需任何GDB设置即可使用
  • 它可以在需要时从c++本身调用

不幸的是,我还没有找到一个完全相同的方式从GDB调用operator<<,真是一团糟:调用operator<<在gdb

这在我的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中测试