如何在gdb postmortem中访问std :: string等STL类?

时间:2015-04-01 21:22:57

标签: gdb core stdstring

我有一个带有std::string的核心转储,我想在gdb中检查。打印它会将其内容作为以空字符结尾的字符串,但如何访问其他std::string属性(如大小和容量)?试图直接访问s.size()会导致错误,“如果没有调试过程,就无法执行此操作。”

1 个答案:

答案 0 :(得分:6)

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

(gdb) disable pretty-printer

对于许多STL课程,他们的成员(希望)不太难以弄明白。例如,打印禁用漂亮打印的std::vector会产生类似于以下内容的输出:

$2 = {, 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无法解析此结构,所以我不得不求助于指针算术黑客。以下是如何使用pre-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]