How to pretty-print STL containers in GDB?

前端 未结 9 557
一整个雨季
一整个雨季 2020-11-30 20:45

I\'ve followed the instructions on the GDB wiki to install the python pretty-printers for viewing STL containers. My ~/.gdbinit now looks like this:

<         


        
相关标签:
9条回答
  • 2020-11-30 21:25

    If you type info type _Rep after the Python exception, gdb will inform you about the classes loaded that match _Rep. That list could help you to find why python cannot find your std::string class.

    I just faced your problem and in my case was intel c compiler, icc, who broke pretty printing. In particular, unqualified icc name for std::string results in:

    std::basic_string<char, std::char_traits<char>, std::allocator<char> >::std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep;
    

    but pretty printer was looking for unqualified gcc name:

    std::basic_string<char, std::char_traits<char>, std::allocator<char>::_Rep;
    

    What I did to solve my problem was modifying class StdStringPrinter in printers.py, adding the unqualified name of the string to the typename to look in gdb. Replacing the line:

    reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
    

    with this:

    reptype = gdb.lookup_type (str (realtype) + '::' + str (realtype) + '::_Rep').pointer ()
    

    With the obtained list from info type you could fix your pretty printers to make them work.

    0 讨论(0)
  • 2020-11-30 21:26

    I ran on this problem and hit this page while trying to figure it out. I eventually fixed it, and I thought it would be worth it to share my experience.

    I am using gcc-5.2, so I downloaded the gcc-5-branch version of pretty printer from the svn repo. However, I had to do these two mods:

    1. when editing the ~/.gdbinit file, the suggested addition is

      python
      import sys
      sys.path.insert(0, '/home/bartgol/.gdb/gdb_printers/python')
      from libstdcxx.v6.printers import register_libstdcxx_printers
      register_libstdcxx_printers (None)
      end
      

    However, I had to comment the line register_libstdcxx_printers (None), since I kept getting an error telling me the libstdcxx_printers were already registered. Apparently they get registered during the import phase.

    1. I had to edit the printers.py file for std::set and std::map. Since the type _Rep_type is private in both. In particular, I replace the routine children in std::map and std::set with the corresponding one in the version of pretty printer from the gcc-4_6-branch version on the svn repo. Got no error ever since, and stuff prints out nicely now.

    Hope this helps.

    0 讨论(0)
  • 2020-11-30 21:28

    It just works on Ubuntu 17.04

    Debian seems to have finally integrated things properly now:

    main.cpp

    #include <map>
    #include <utility>
    #include <vector>
    
    int main() {
        std::vector<int> v;
        v.push_back(0);
        v.push_back(1);
        v.push_back(2);
        std::map<int,int> m;
        m.insert(std::make_pair(0, 0));
        m.insert(std::make_pair(1, -1));
        m.insert(std::make_pair(2, -2));
    }
    

    Compile:

    g++ -O0 -ggdb3 -o main.out -std=c++98 main.cpp
    

    Outcome:

    (gdb) p v
    $1 = std::vector of length 3, capacity 4 = {0, 1, 2}
    (gdb) p m
    $2 = std::map with 3 elements = {[0] = 0, [1] = -1, [2] = -2}
    

    We can see that the pretty printer is installed with:

    (gdb) info pretty-printer
    

    Which contains the lines:

    global pretty-printers:
      objfile /usr/lib/x86_64-linux-gnu/libstdc++.so.6 pretty-printers:
      libstdc++-v6
        std::map
        std::vector
    

    The printers are provided by the file:

    /usr/share/gcc-7/python/libstdcxx/v6/printers.py
    

    which comes with the main C++ library package libstdc++6 and is located under libstdc++-v3/python/libstdcxx in the GCC source code: https://github.com/gcc-mirror/gcc/blob/gcc-6_3_0-release/libstdc%2B%2B-v3/python/libstdcxx/v6/printers.py#L244

    TODO: how GDB finds that file is the final mistery, it is not in my Python path: python -c "import sys; print('\n'.join(sys.path))" so it must be hardcoded somewhere?

    Custom classes

    See how to define a custom toString method and call it at: Printing C++ class objects with GDB

    0 讨论(0)
提交回复
热议问题