29

I have a std::vector as part of a class, that contains a custom type. Its contents seems to be mysteriously changed from somewhere in the program. I am having trouble trying to figure out where this is happening.

Is there a way to "watch" the contents (or size) of a std::vector from gdb?

Thanks.

endbegin
  • 1,610
  • 1
  • 17
  • 18
  • Can you isolate and define the code parts between where the size increase happens and provide a little bit of more information (e.g. what is your custom type, does itself allocate memory etc.)? You could still place a breakpoint within the allocate() of the vector as std::vector should have a template implementation only, so the source shall be accessible. – cli_hlt Nov 23 '11 at 21:15
  • I know where the size increase happens, but when the size function is called at a later point by another function, it reports its size as 0, and I cannot seem to figure out where. The vector contains pointers to a data structure that does not do explicit new/delete. – endbegin Nov 23 '11 at 21:50
  • Then maybe it would help if you'd showed us some code concerning that particular area. Otherwise (and regarding your comment to the first posted answer) my voodoo clang only shows me silence ;o) – cli_hlt Nov 23 '11 at 22:07
  • Hmm ... let me think about how to show code that would could help. I can't think of an easy way to show the code without getting into program's class structure ... – endbegin Nov 24 '11 at 02:41

2 Answers2

19

Is there a way to "watch" the contents (or size) of a std::vector from gdb?

Assuming you are using GCC, set watchpoints on theVector->_M_impl._M_start and _M_finish. If you are using some other std::vector implementation, adjust accordingly.

Example:

#include <vector>

int main()
{
  std::vector<int> v;

  v.push_back(1);
  v.push_back(2);
}

g++ -g t.cc
gdb -q ./a.out

Reading symbols from /tmp/a.out...done.
(gdb) start
Temporary breakpoint 1 at 0x40090f: file t.cc, line 5.

Temporary breakpoint 1, main () at t.cc:5
5     std::vector<int> v;
(gdb) n
7     v.push_back(1);
(gdb) p v._M_impl._M_start
$1 = (int *) 0x0
(gdb) p v._M_impl._M_finish 
$2 = (int *) 0x0
(gdb) p &v._M_impl._M_finish
$3 = (int **) 0x7fffffffd878
(gdb) watch *$3
Hardware watchpoint 2: *$3
(gdb) p &v._M_impl._M_start
$4 = (int **) 0x7fffffffd870
(gdb) watch *$4
Hardware watchpoint 3: *$4
(gdb) c
Hardware watchpoint 3: *$4

Old value = (int *) 0x0
New value = (int *) 0x604010
std::vector<int, std::allocator<int> >::_M_insert_aux (this=0x7fffffffd870, __position=0x0) at /usr/include/c++/4.4/bits/vector.tcc:365
365       this->_M_impl._M_finish = __new_finish;
(gdb) bt
#0  std::vector<int, std::allocator<int> >::_M_insert_aux (this=0x7fffffffd870, __position=0x0) at /usr/include/c++/4.4/bits/vector.tcc:365
#1  0x0000000000400a98 in std::vector<int, std::allocator<int> >::push_back (this=0x7fffffffd870, __x=@0x7fffffffd88c) at /usr/include/c++/4.4/bits/stl_vector.h:741
#2  0x0000000000400935 in main () at t.cc:7
(gdb) c
Hardware watchpoint 2: *$3

Old value = (int *) 0x0
New value = (int *) 0x604014
std::vector<int, std::allocator<int> >::_M_insert_aux (this=0x7fffffffd870, __position=0x0) at /usr/include/c++/4.4/bits/vector.tcc:366
366       this->_M_impl._M_end_of_storage = __new_start + __len;
(gdb) bt
#0  std::vector<int, std::allocator<int> >::_M_insert_aux (this=0x7fffffffd870, __position=0x0) at /usr/include/c++/4.4/bits/vector.tcc:366
#1  0x0000000000400a98 in std::vector<int, std::allocator<int> >::push_back (this=0x7fffffffd870, __x=@0x7fffffffd88c) at /usr/include/c++/4.4/bits/stl_vector.h:741
#2  0x0000000000400935 in main () at t.cc:7

... etc...
Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • 2
    Could you explain your method in detial since I still could not understand your method? Thanks a lot. – xiao 啸 Dec 20 '12 at 07:11
  • 2
    *$1*, *$2*, ... are gdb [values](https://ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_58.html#:~:text=Values). They can be used in expressions. In this case you keep a pointer *$3* to _M_finish variable, which points to the last value. Then you *watch* for value (\*$3) which it is points to, so, when _M_finish changed (new element added/deleted) you will hit watchpoint. – folq Mar 04 '21 at 08:52
1

I think that http://sourceware.org/gdb/wiki/STLSupport will be helpful.

Hauleth
  • 22,873
  • 4
  • 61
  • 112
  • I tried that, but all I could glean from there is a way to pretty-print a std::vector. Not sure how to watch it though ... – endbegin Nov 23 '11 at 21:56