First let’s talk about custom containers. GDB would show the field names of an object, but frequently not the values. I guess integers values might show up but more than half the fields are pointers ( actually char-array field would be easy to print.)
If I call a function on the object, I have to be very lucky and very careful. q(->) has never worked for me so far, so I need to use q(*) to de-reference every pointer before calling a method on the pointee, and pray it works.
http://www.yolinux.com/TUTORIALS/src/dbinit_stl_views-1.03.txt works on std::map …
A simple experiment using https://github.com/tiger40490/repo1/blob/cpp1/cpp/88miscLang/containerDumpOperator.cpp
- g++ -g theFile.cpp && gdb -iex ‘add-auto-load-safe-path .’ ./a.out
- (gdb) print *(li._M_impl._M_start+1) # can print 2nd element if it’s std::string or double
- Note before vector initialization, gdb already shows the addresses inside the vector, but some addresses are not populated. Just retry after the initialization.
- std::unordered_map is doable:
- (gdb) print **(tm._M_buckets) # prints first pair in a hash table bucket
- (gdb) print *((**(tm._M_buckets))._M_next) # next pair in the same bucket
- std::map content is harder
- (gdb) print *(int*)(tm._M_t._M_impl._M_header._M_left+1) # prints one key
- (gdb) print *(int*)(tm._M_t._M_impl._M_header._M_right+1) # prints another key in the pair
- (gdb) print *(int*)((void*)(tm._M_t._M_impl._M_header._M_right+1)+sizeof(int)) #prints the value in the pair.
- the (void*) is needed before we add sizeof(value_type). Without the cast, the pointer arithmetic would be different.
- from the key field to value field, we move by 4 bytes (i.e. sizeof value_type) from 0x6050e0 to 0x6050e4. It’s actually easy to manually type .. print *0x6050e4
- I suspect the _M_right pointer is seated at the “color” field. Increment to the key field?