106

Supposing to have something like this:

#include <map>
int main(){
    std::map<int,int> m;
    m[1] = 2;
    m[2] = 4;
    return 0;
}

I would like to be able to inspect the contents of the map running the program from gdb.
If I try using the subscript operator I get:

(gdb) p m[1]
Attempt to take address of value not located in memory.

Using the find method does not yield better results:

(gdb) p m.find(1)
Cannot evaluate function -- may be inlined

Is there a way to accomplish this?

Paolo Tedesco
  • 55,237
  • 33
  • 144
  • 193
  • 1
    To print all elements without truncating large maps: https://stackoverflow.com/questions/47743215/having-gdb-print-a-big-stdmap-fully-while-debugging A more "Cannot evaluate function maybe inlined" focused: https://stackoverflow.com/questions/40633787/c-stl-gdb-cannot-evaluate-function-maybe-inlined – Ciro Santilli OurBigBook.com Sep 24 '20 at 12:09
  • General question: [c++ - How to pretty-print STL containers in GDB? - Stack Overflow](https://stackoverflow.com/questions/11606048/how-to-pretty-print-stl-containers-in-gdb) – user202729 Dec 04 '21 at 08:04

7 Answers7

113

The existing answers to this question are very out of date. With a recent GCC and GDB it Just WorksTM thanks to the built-in Python support in GDB 7.x and the libstdc++ pretty printers that come with GCC.

For the OP's example I get:

(gdb) print m
$1 = std::map with 2 elements = {[1] = 2, [2] = 4}

If it doesn't work automatically for you see the first bullet point on the STL Support page of the GDB wiki.

You can write Python pretty printers for your own types too, see Pretty Printing in the GDB manual.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • Thanks for the answer... actually the question itself is rather out of date by now :) – Paolo Tedesco Mar 11 '13 at 07:53
  • 3
    Yes, but other questions are getting closed as duplicates of it, so I wanted it to have recent information. – Jonathan Wakely Mar 11 '13 at 09:12
  • 1
    I am using GDB 7.2 and the above works ... if you have a small collection. I still haven't found any way to print say element 1543 from a 4K vector, other than resorting to using internal structures of the STL implementation. – pavon Oct 09 '13 at 18:35
  • @pavon, did you try `print vec[1543]`? that works perfectly for me with GDB 7.6 – Jonathan Wakely Oct 09 '13 at 22:42
  • 5
    Yes, in GDB 7.2 and the icpc compiler I get the error `Could not find operator[]`. – pavon Oct 09 '13 at 23:19
  • 13
    Unfortunately it doesn't "Just Work" in all the distros. It isn't installed by default in Ubuntu 13.10 and there are [problems when you try to install it manually](http://askubuntu.com/questions/403143/setting-up-gdb-pretty-printing-in-ubuntu-13-10) – nietaki Jan 09 '14 at 22:18
  • That shows the entire map. The OP asked how to show a specific element of the map. –  Apr 24 '14 at 13:43
  • @user570500, that's one way to interpret it. The OP asks "I would like to be able to inspect the contents of the map running the program from gdb. [...] Is there a way to accomplish this?" My answer shows a way to inspect the contents. – Jonathan Wakely Apr 25 '14 at 18:55
  • @JonathanWakely Which distro are you using where it just works? – razeh Jun 20 '14 at 15:02
  • 1
    @razeh, Fedora, RHEL (and RHEL clones). There's a fix in progress to make the printers also work on distros where GDB is linked to Python 3 – Jonathan Wakely Jul 10 '14 at 16:33
  • The upstream GCC code has been fixed to work with Python3, so it should work in Ubuntu and Debian soon – Jonathan Wakely Aug 29 '14 at 11:52
  • This needs a definition of "recent" .... it's not very useful for the people stuck on "not recent" if they don't know what they need to update to – UKMonkey Nov 22 '18 at 18:09
  • @UKMonkey given that the answer is over five years old, "something less than six years old" would be a fairly obvious (and conservative) guess. It looks like the libstdc++ printers were added for GCC 4.5.0 which was released in 2010. Some distros backported them to GCC 4.4, and maybe earlier. – Jonathan Wakely Nov 22 '18 at 19:56
  • @JonathanWakely :) I don't disagree... but, the gdb I'm stuck with is "really quite old" (excess of 8 years) which is why I made my comment and it doesn't seem to Just work (tm). Sad times - more googling required I guess! – UKMonkey Nov 23 '18 at 09:02
  • @UKMonkey if you're asking about GDB, the answer already says GDB 7.x (and has done since 2013). – Jonathan Wakely Nov 23 '18 at 10:57
  • And the "STL Support" link I gave in the answer says "GDB 7.0 will include support for writing pretty-printers in Python." – Jonathan Wakely Nov 23 '18 at 11:17
  • Is it possible to print the implementation/body of a `std::function` by GDB? – skytree Mar 09 '19 at 10:45
  • @skytree that should really be a separate question, or on the gcc-help mailing list, not as a comment on a question about std::map. The answer is no, but somebody could write a printer for it. – Jonathan Wakely Mar 09 '19 at 11:02
  • @JonathanWakely Thank you. Could you please offer me a reference link about that printer or just related posts? – skytree Mar 09 '19 at 11:21
36

I think there isn't, at least not if your source is optimized etc. However, there are some macros for gdb that can inspect STL containers for you:

http://sourceware.org/ml/gdb/2008-02/msg00064.html

However, I don't use this, so YMMV

jpalecek
  • 47,058
  • 7
  • 102
  • 144
  • 1
    Thanks for the link; the only thing is that macros are dependent from the stl libraries version, which I'd prefer to avoid. +1 – Paolo Tedesco Jan 09 '09 at 10:41
  • Its also a bit frustrating that commands like "plist foo std::string" give syntax errors. It appears that the value_type can't contain any punctuation. – Bklyn Jan 09 '09 at 21:49
  • 2
    I haven't tried, but if this works the same as the rest of GDB, enclosing the name with punctuated name in single quotes should do it. – jpalecek Jan 09 '09 at 23:35
  • 2
    Note: the std::map functionality in these scripts assumes 32-bit pointer types. For 64-bit machines, replace "+ 4" to "+ 8" everywhere in the file. – Kyle Simek May 20 '12 at 20:22
  • pvector isn't defined in my gdb (version 7.5.91.20130417-cvs-ubuntu). – Jeff Jul 22 '13 at 16:21
25

There's always the obvious: Define your own test-function... Call it from gdb. E.g.:

#define SHOW(X) cout << # X " = " << (X) << endl

void testPrint( map<int,int> & m, int i )
{
  SHOW( m[i] );
  SHOW( m.find(i)->first );
}

int
main()
{
    std::map<int,int> m;
    m[1] = 2;
    m[2] = 4;
    return 0;  // Line 15.
}

And:

....
Breakpoint 1 at 0x400e08: file foo.C, line 15.
(gdb) run
Starting program: /tmp/z/qD 

Breakpoint 1, main () at qD.C:15
(gdb) call testPrint( m, 2)
m[i] = 4
(*m.find(i)).first = 2
(gdb) 
Mr.Ree
  • 8,320
  • 27
  • 30
  • 19
    as long as the process is running. not so useful for core-dumps. – sean riley Aug 14 '09 at 00:15
  • 2
    This is useful advice debug GDB in general, not just with STL. I keep a whole library of gdb helper functions for lots of hard-to-retrieve data, e.g. write_cuda_array_as_image(). Note that some compilers will strip out any functions that aren't called, so I place a call to each helper function after my main's "return 0;". Also declaring them with extern "C" makes calling them from gdb easier. – Kyle Simek May 20 '12 at 20:30
  • 1
    @KyleSimek gcc also supports ` __attribute__((used))` so the linker won't toss the symbol if unused – Dodgie Jun 02 '21 at 14:15
21

The stl-views.gdb used to be the best answer there was, but not anymore.

This isn't integrated into the mainline GDB yet, but here is what you get using the 'archer-tromey-python' branch:

(gdb) list
1   #include <map>
2   int main(){
3       std::map<int,int> m;
4       m[1] = 2;
5       m[2] = 4;
6       return 0;
7   }
(gdb) break 6
Breakpoint 1 at 0x8048274: file map.cc, line 6.
(gdb) run

Breakpoint 1, main () at map.cc:6
6       return 0;
(gdb) print m
$1 = std::map with 2 elements = {
  [1] = 2,
  [2] = 4
}
(gdb) quit
Employed Russian
  • 199,314
  • 34
  • 295
  • 362
13

Try De-Referencing STL Containers: on this page: http://www.yolinux.com/TUTORIALS/GDB-Commands.html

anand
  • 617
  • 1
  • 5
  • 6
3

The answers above are working and fine. In case you are using stl-views.gdb, here is the proper way of viewing the maps and elements inside it. Let your map is as follows : std::map<char, int> myMap;

(gdb) pmap myMap char int

i.e. pmap <variable_name> <left_element_type> <right_element_type> to see the elements in the map.

Hope that helps.

Mazhar MIK
  • 1,022
  • 12
  • 14
  • `stl-views` is outdated, gdb has pretty print after 7.0. The instruction [here](http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug.html#debug.gdb) – Louis Go Feb 21 '23 at 03:23
-1

You can get around the second problem (Cannot evaluate function -- may be inlined) by making sure that your compiler uses DWARF-2 (or 3 or 4) debugging information when you compile your program. DWARF-2 includes inlining information, so you should be able to use either of the methods you described to access elements of your std::map container.

To compile with DWARF-2 debug info, add the -gdwarf-2 flag to your compile command.

Dan
  • 12,157
  • 12
  • 50
  • 84
  • 1
    Um, knowing where a function has been inlined does not make it possible for GDB to evaluate calls to that function; GDB really needs access to an out-of-line copy of the function! – SamB Feb 03 '15 at 03:09