Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a core dump with a std::string that I'd like to inspect in gdb. Printing it gives me its contents as a null-terminated string, but how do I access other std::string properties such as size and capacity? Trying to access s.size() directly results in an error, "You can't do that without a process to debug."

like image 523
Josh Kelley Avatar asked Apr 01 '15 21:04

Josh Kelley


1 Answers

First, disable any pretty-printers to see the raw member variables of the structure you're trying to print.

(gdb) disable pretty-printer

For many STL classes, their members are (hopefully) not too hard to figure out. For example, printing a std::vector with pretty-printing disabled gives output similar to the following:

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

Since the member variables are _M_impl._M_start, _M_impl._M_finish, and _M_impl._M_end_of_storage, you can use them as follows for a vector v:

  • element 0 - _M_impl._M_start[0]
  • size - v._M_impl._M_end - v._M_impl._M_start
  • capacity - v._M_impl._M_end_of_storage - v._M_impl._M_start

std::string in particular is harder. libstdc++'s implementation shows that the capacity, size, and reference count are stored before the beginning of the string, in a std::basic_string::_Rep structure, and gdb has trouble resolving this structure, so I had to resort to pointer arithmetic hacks. Here's how to do it for a string s in a 32-bit x86 app with the pre-C++11 ABI; other platforms may differ.

  • reference count - ((int*)s._M_dataplus._M_p)[-1]
  • capacity - ((int*)s._M_dataplus._M_p)[-2]
  • size - ((int*)s._M_dataplus._M_p)[-3]
like image 85
Josh Kelley Avatar answered Sep 28 '22 06:09

Josh Kelley