Search code examples
c++cgdbbinaryfilescoredump

How to output a HashMap element in GDB?


All I have is a binary file and a coredump, and I need to return the value of the vector element in hashmap[8888][1] using a gdb script at the time of the program crash. While the program was running, the container was damaged, but it is claimed that the necessary data can be obtained. The question is how to use pointers or something else to get to the desired vector and pull out the element I need?

(gdb) p hashmap
$1 = std::unordered_map with 5 elements
(gdb) ptype hashmap
type = std::unordered_map<int, std::vector<int>>
(gdb) p *(&hashmap - 2)
$2 = std::unordered_map with 94366596825088 elements = {[88888] = std::vector of length 3, capacity 3 = {1706628932, 1495493257, 18800028}, [8888] = std::vector of length 3, capacity 3 = {1254516933, 
    1257973910, 1938010846}, [888] = std::vector of length 3, capacity 3 = {1976864792, 130725599, 41716398}, [8] = std::vector of length 3, capacity 3 = {1533274456, 1112929722, 1834506749}, 
  [88] = std::vector of length 3, capacity 3 = {1297327512, 118122261, 1973236149}}

Solution

  • Normally, print hashmap should produce all the output you need.

    For example, compiling this program:

    #include <unordered_map>
    #include <vector>
    
    int main(int arch, char *argv[])
    {
      std::unordered_map<int, std::vector<int>> hm;
      hm[7777].push_back(42);
      hm[7777].push_back(24);
      hm[8888].push_back(42);
      return 0;
    }
    

    and running it under GDB results in:

    (gdb) p hm
    $1 = std::unordered_map with 2 elements = {[8888] = std::vector of length 1, capacity 1 = {42}, [7777] = std::vector of length 2, capacity 2 = {42, 24}}
    

    We can see in your output that the python pretty printer started doing it's job, but somehow failed mid-sentence.

    This can happen for a large number of reasons, from bad versions of gcc or gdb, to incorrectly installed libstdc++, and on and on.

    Your question lacks all relevant details.

    For a start, you should try to replicate the output from above program. If that works, supply versions of GCC, GDB, libstdc++, and we can make further guesses.

    Update:

    container is slightly corrupted

    Ah, that is another reason for the standard pretty-printer to not work.

    I want to understand how to pull it out using a gdb script.

    In the case of memory corruption you will have to grovel in raw memory, there is no shortcut (and the data isn't even guaranteed to be present).

    You will have to read and understand the implementation details of std::unordered_map. Reading the pretty-printer for it (usually installed to /usr/share/gdb/python/gdb/libstdcxx/v6/printers.py) can help.