I use Ubuntu 20.04-LTS with WSL(Windows Subsystem Linux), GDB version is 9.2, and I builded my c++ code with c++11.
I tried to access std::map's value with index in GDB, however GDB showed error message "Invalid cast".
My code is same for below
#include <iostream>
#include <map>
#include <string>
using std::cout;
using std::map;
using std::string;
using std::to_string;
int main()
{
map<string, int> si;
for(int i = 0; i < 10; ++i)
{
si[to_string(i)] = i;
}
for(int i = 0; i < 10; ++i)
{
cout << si[to_string(i)] << "\n";
}
}
And, in GDB
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ctest...
(gdb) l main
6 using std::map;
7 using std::string;
8 using std::to_string;
9
10 int main()
11 {
12 map<string, int> si;
13
14 for(int i = 0; i < 10; ++i)
15 {
(gdb) l 15
10 int main()
11 {
12 map<string, int> si;
13
14 for(int i = 0; i < 10; ++i)
15 {
16 si[to_string(i)] = i;
17 }
18
19 for(int i = 0; i < 10; ++i)
(gdb) b 18
Breakpoint 1 at 0x2579: file ctest.cpp, line 19.
(gdb) r
Starting program: /home/lksj/ctest
Breakpoint 1, main () at ctest.cpp:19
19 for(int i = 0; i < 10; ++i)
(gdb) p si["1"]
Invalid cast.
(gdb)
How can I access the std::map object value directly with index in GDB?
You first write the below code in the ".gdbinit" file.
define newstr
set ($arg0)=(std::string*)malloc(sizeof(std::string))
call ($arg0)->basic_string()
# 'assign' returns *this; casting return to void avoids printing of the
struct.
call (void)( ($arg0)->assign($arg1) )
end
define delstr
call ($arg0)->~basic_string(0)
# ^
call free($arg0)
set ($arg0)=(void*)0
end
And then write the below function in your c++ code.
void indexing_map( map<string,[type]> & m, string i )
{
cout << m[i] << "\n";
}
Now, all things are ready. You just execute gdb for debugging your code with the
newstr $foo [any string of map of the key]
For example,
example.cpp
#include <iostream>
#include <unordered_map>
#include <string>
using std::cout;
using std::unordered_map;
using std::string;
void indexing_map(unordered_map<string, int> &m, string i)
{
cout << m[i] << "\n";
}
int main()
{
unordered_map<string, int> st_in;
st_in["1"] = 1;
st_in["2"] = 2;
st_in["3"] = 3;
indexing_map(st_in, "1");
return 0;
}
and gdb
(gdb) b 25
Breakpoint 1 at 0x28d6: file ctest.cpp, line 25.
(gdb) r
Starting program: /home/user/ctest
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, main () at ctest.cpp:25
25 st_in["3"] = 3;
(gdb) newstr $foo "1"
(gdb) call indexing_map(st_in , *$foo)
1