Search code examples
gdbstdstringcoredump

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


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."


Solution

  • 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]