I want to examine the contents of a std::vector in GDB, how do I do it? Let's say it's a std::vector<int> for the sake of simplicity.
-
3Similar question: stackoverflow.com/questions/427589/… (the link in the answer is very interesting).Paolo Tedesco– Paolo Tedesco2009-06-26 15:47:49 +00:00Commented Jun 26, 2009 at 15:47
-
1The new, better way to do this is in this question: stackoverflow.com/questions/2492020/…dshepherd– dshepherd2013-04-19 11:19:09 +00:00Commented Apr 19, 2013 at 11:19
-
Or c++ - How to pretty-print STL containers in GDB? - Stack Overflowuser202729– user2027292021-12-04 07:20:05 +00:00Commented Dec 4, 2021 at 7:20
7 Answers
With GCC 4.1.2, to print the whole of a std::vector<int> called myVector, do the following:
print *(myVector._M_impl._M_start)@myVector.size()
To print only the first N elements, do:
print *(myVector._M_impl._M_start)@N
Explanation
This is probably heavily dependent on your compiler version, but for GCC 4.1.2, the pointer to the internal array is:
myVector._M_impl._M_start
And the GDB command to print N elements of an array starting at pointer P is:
print P@N
Or, in a short form (for a standard .gdbinit):
p P@N
9 Comments
Cannot evaluate function -- may be inlined_M_impl etc) for your compiler under GDB 7.0+, use print /r myVectorTo view vector std::vector myVector contents, just type in GDB:
(gdb) print myVector
This will produce an output similar to:
$1 = std::vector of length 3, capacity 4 = {10, 20, 30}
To achieve above, you need to have gdb 7 (I tested it on gdb 7.01) and some python pretty-printer. Installation process of these is described on gdb wiki.
What is more, after installing above, this works well with Eclipse C++ debugger GUI (and any other IDE using GDB, as I think).
3 Comments
$HOME/.gdbinit was necessary. At the moment I end up with no such file at all and gdb correctly showing the content of std::vector. However, since during my "rambling" attempts I just installed and then unistalled cgdb, and I already had libstdc++5 installed, I have no idea why the pretty printing did not work while now it works.Put the following in ~/.gdbinit:
define print_vector
if $argc == 2
set $elem = $arg0.size()
if $arg1 >= $arg0.size()
printf "Error, %s.size() = %d, printing last element:\n", "$arg0", $arg0.size()
set $elem = $arg1 -1
end
print *($arg0._M_impl._M_start + $elem)@1
else
print *($arg0._M_impl._M_start)@$arg0.size()
end
end
document print_vector
Display vector contents
Usage: print_vector VECTOR_NAME INDEX
VECTOR_NAME is the name of the vector
INDEX is an optional argument specifying the element to display
end
After restarting gdb (or sourcing ~/.gdbinit), show the associated help like this:
gdb) help print_vector
Display vector contents
Usage: print_vector VECTOR_NAME INDEX
VECTOR_NAME is the name of the vector
INDEX is an optional argument specifying the element to display
Example usage:
(gdb) print_vector videoconfig_.entries 0
$32 = {{subChannelId = 177 '\261', sourceId = 0 '\000', hasH264PayloadInfo = false, bitrate = 0, payloadType = 68 'D', maxFs = 0, maxMbps = 0, maxFps = 134, encoder = 0 '\000', temporalLayers = 0 '\000'}}
2 Comments
'Watching' STL containers while debugging is somewhat of a problem. Here are 3 different solutions I have used in the past, none of them is perfect.
Use GDB scripts from http://clith.com/gdb_stl_utils/ These scripts allow you to print the contents of almost all STL containers. The problem is that this does not work for nested containers like a stack of sets.
Visual Studio 2005 has fantastic support for watching STL containers. This works for nested containers but this is for their implementation for STL only and does not work if you are putting a STL container in a Boost container.
Write your own 'print' function (or method) for the specific item you want to print while debugging and use 'call' while in GDB to print the item. Note that if your print function is not being called anywhere in the code g++ will do dead code elimination and the 'print' function will not be found by GDB (you will get a message saying that the function is inlined). So compile with -fkeep-inline-functions
Comments
This is an add-up to the answer by Michał Oniszczuk.
According to this post in the issue, if you are using VSCode for development and your OS is Ubuntu 22.04, you can simply add the following code in your launch.json file.
"setupCommands": [
{
"description": "Test",
"text": "python import sys;sys.path.insert(0, '/usr/share/gcc/python');from libstdcxx.v6.printers import register_libstdcxx_printers;register_libstdcxx_printers(None)",
"ignoreFailures": false
},
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
This method simplified the answer mentioned in the gdb wiki above, since you don't have to manually specify the Python module or put this script in the .gdbinit file. And I believe this also answers the question raised by @Enlico in his comment.
By the way, if you are using Python C++ debugger in the VSCode like I do, you can use the following launch.json file out-of-the-box.
{
"version": "0.2.0",
"configurations": [
{
"name": "Python C++ Debug",
"type": "pythoncpp",
"request": "launch",
"pythonConfig": "default",
// "cppConfig": "default (gdb) Attach",
"cppAttachName": "(gdb) Attach",
"preLaunchTask": "Build" // Specify your own build task here.
},
{
"name": "(gdb) Attach",
"type": "cppdbg",
"request": "attach",
"processId": "",
"setupCommands": [
{
"description": "Test",
"text": "python import sys;sys.path.insert(0, '/usr/share/gcc/python');from libstdcxx.v6.printers import register_libstdcxx_printers;register_libstdcxx_printers(None)",
"ignoreFailures": false
},
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
You might get a warning indicating "Missing Property 'Program'", but it seems everything works fine.
Comments
The accepted answer (Michał's) should work with recent versions of gdb. But a "full-featured" gdb is required.
On Debian 12, two packages gdb (full-featured) and gdb-minimal provide command gdb, version 13:
gdbfrom packagegdbcould print content ofstd::vector.gdbfrom packagegdb-minimalcould not directly print the content ofstd::vector.