【问题标题】:Printing C++ class objects with GDB使用 GDB 打印 C++ 类对象
【发布时间】:2013-03-01 17:18:12
【问题描述】:

当我们调试 C++ 应用程序时,是否有一些“默认函数”可以在 GDB 上打印字符串等对象?类似于:toString();

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

【问题讨论】:

标签: c++ debugging gdb


【解决方案1】:

您总是可以使用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 是不够的,输出是由最新版本的 GCC 附带的漂亮打印机完成的,使用最新版本的 GDB 中的嵌入式 Python 解释器
  • @JonathanWakely:正确。说工具链可能比 gdb 更合适......这些东西通常默认安装在大多数“用户友好”发行版中的开发包中。
【解决方案2】:

您可以在调试会话期间从标准库或您自己的数据类型中call any member functions。这有时是在 gdb 中输出对象状态的最简单方法。对于std::string,您可以将其称为c_str() 成员,该成员返回const char*

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

虽然这仅适用于调试实时进程,但不适用于核心转储调试。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      定义operator&lt;&lt;并从GDB调用它

      在 cmets 中提到了C++ equivalent of Java's toString?operator&lt;&lt; 是在类上定义转字符串方法的最常见方式。

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

      • 停止编译更不容易(希望!)
      • 无需任何 GDB 设置即可轻松使用
      • 可以在需要时从 C++ 自身调用

      不幸的是,我还没有找到从 GDB 调用 operator&lt;&lt; 的完全理智的方法,真是一团糟:calling operator<< in 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 中测试。

      【讨论】:

        猜你喜欢
        • 2011-09-05
        • 1970-01-01
        • 1970-01-01
        • 2021-10-15
        • 1970-01-01
        • 1970-01-01
        • 2011-06-26
        • 2019-03-24
        • 2014-02-01
        相关资源
        最近更新 更多