gdb: dump STL container %%experience

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. works on std::map …

A simple experiment using

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

loading .gdbinit

My experiments show that $HOME/.gdbinit is discovered. I actually changed the $HOME env variable:)

However, I hit

  warning: not using untrusted file "/v/global/user/b/bi/bint/.gdbinit"

, even though I added q(gdb -iex ‘set auto-load safe-path …’). I guess the warning come up before the -iex option takes effect

  gdb -ix '/path/to/.gdbinit' # also failed due to untrusted file
  g++ -std=c++0x -g dump.cpp && gdb -iex 'add-auto-load-safe-path .' ./a.out # working

gdb symbol-loading too time-consuming

After I attach gdb, it immediately starts a prolonged symbol loading process. It’s better to skip the loading, and selectively load some symbols. describes how to use ~/.gdbinit, but I had no permission to write to the ~/

gdb -iex ‘set auto-solib-add off’ …. # worked

–loading a particular *.so file

I got “No loaded shared libraries match the pattern” and fixed it by

shar #instead of /full/path/to/

g++ q[-L] vs [-l] .. [-I] vs [-isystem]

-L and -l (i.e. the big and small "L") both affect the linker only.

See also MSVS linker option -L vs -l #small L

-L (similar to -I) and introduces a new search directory, for *.so or *.a file search.

Q: does the order of -l options matter?
A: yes. Recall the -liberty …

Q: does the order of -L options matter?

-I and -isystem both affect the preprocessor only.

There’s not “-i” option per-se.


github tips #basic

  • q(git config credential.helper store) is the command that finally fixed my git-bash forgetting-password problem on my win7 Dell. The github recommended command only worked in my win10 Lenovo and office win7:
    • git config --global credential.helper wincred 
  • –to download an entire branch on the github web interface: CloneOrDownload button can download a zipfile
  • –to mass upload using drag-n-drop
  • I realize that the zipfile downloaded has a problem. When I open the zipfile (but not extract) and select the files, the drag-n-drop interface fails. I had to copy the files to a tmp directory.
  • –delete folder: not so easy
  • –file naming tips
    • ^ is slightly less ideal
    • I would use underscore as default and use dash sparingly (like 0-N). Camel case is even better.
  • –rename file @web interface is easy
    • checkout branch locally,
    • rename branch
    • commit
    • push, which triggered a login pop-up.–rename branch: no web interface. I had to
  • –rename folder: no web interface. I had to
    • git mv dir1 com/xx/dir1 # close MSWE if you get perm error
    • git commit
    • git push

g++ -D_GLIBCXX_DEBUG #impractical

This is a good story for interviews.

In a simple program I wrote from scratch, this flag saved the day. My input to std::set_difference was not sorted, as detected by this flag. Without this flag, the compiler didn’t complain and I had some unexpected successful runs, but with more data I hit runtime errors.

I had less luck using this flag with an existing codebase. After I build my program with this flag, I got random run-time crashes due to “invalid pointer at free()” whenever i use a std::stringstream.