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

Jos*_*ley 4 gdb core stdstring

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

Jos*_*ley 6

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

(gdb) disable pretty-printer
Run Code Online (Sandbox Code Playgroud)

对于许多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 ++的实现显示容量,大小和引用计数存储在字符串的开头之前,在std::basic_string::_Rep结构中,并且gdb无法解析此结构,所以我不得不求助于指针算术黑客.以下是如何s使用pre-C++ 11 ABI在32位x86应用程序中为字符串执行此操作; 其他平台可能不同.

  • 参考计数 - ((int*)s._M_dataplus._M_p)[-1]
  • 容量 - ((int*)s._M_dataplus._M_p)[-2]
  • 大小 - ((int*)s._M_dataplus._M_p)[-3]