我如何在 gdb postmortem 中像 std::string 一样访问 STL 类?

How do I access STL classes like std::string in gdb postmortem?

我有一个带有 std::string 的核心转储,我想在 gdb 中检查它。打印它给我它的内容作为空终止字符串,但我如何访问其他 std::string 属性,如大小和容量?尝试直接访问 s.size() 导致错误,"You can't do that without a process to debug."

首先,禁用任何漂亮的打印机以查看您尝试打印的结构的原始成员变量。

(gdb) disable pretty-printer

对于许多 STL 类,他们的成员(希望)不难理解。例如,在禁用漂亮打印的情况下打印 std::vector 会产生类似于以下内容的输出:

 = {, std::allocator >, std::allocator, std::allocator > > >> = {
    _M_impl = {, std::allocator > >> = {, std::allocator > >> = {}, }, _M_start = 0x804b028, _M_finish = 0x804b02c,
      _M_end_of_storage = 0x804b02c}}, }

由于成员变量是_M_impl._M_start_M_impl._M_finish_M_impl._M_end_of_storage,你可以像下面这样使用它们作为向量v:

  • 元素 0 - _M_impl._M_start[0]
  • 尺寸 - v._M_impl._M_end - v._M_impl._M_start
  • 容量 - v._M_impl._M_end_of_storage - v._M_impl._M_start

std::string 特别难。 libstdc++'s implementation 显示容量、大小和引用计数存储在字符串开头之前的 std::basic_string::_Rep 结构中,而 gdb 无法解析此结构,因此我不得不求助于指针算术黑客.以下是如何在具有 C++11 之前的 ABI 的 32 位 x86 应用程序中对字符串 s 执行此操作;其他平台可能不同。

  • 引用计数 - ((int*)s._M_dataplus._M_p)[-1]
  • 容量 - ((int*)s._M_dataplus._M_p)[-2]
  • 尺寸 - ((int*)s._M_dataplus._M_p)[-3]