Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get specific std::map value with indexing while using gdb for debuggin c++ code?

Tags:

c++

gdb

stdmap

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?

like image 404
lksj Avatar asked Jan 19 '26 14:01

lksj


1 Answers

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
like image 141
lksj Avatar answered Jan 22 '26 05:01

lksj



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!