Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gdb Could not find operator[]

Tags:

c++

vector

gdb

double var1, var2;
std::vector<double *> x;

var1 = 1;
var2 = 2;

x.push_back(&var1);
x.push_back(&var2);

When I debug this code in gdb and try print x[0] or *x[0] I get:

Could not find operator[].

Now if I include this line after the push_back:

x[0] = &var1;

I can access any specific elements in gdb. The same thing happens with other members such as front(), at(), etc. My understanding is that the compiler/linker includes only the member functions present in the source code and those are the ones I can use in gdb. Is there a way to include every member function of std::vector so I can access them in gdb?

like image 508
m3phi Avatar asked Jun 09 '14 22:06

m3phi


3 Answers

My understanding is that the compiler/linker includes only the member functions present in the source code and those are the ones I can use in gdb.

Your understanding is incorrect / incomplete.

std::vector is a template class. Without explicit instantiation, the compiler is required to instantiate only the methods called (usually a subset of methods present in the source).

Is there a way to include every member function of std::vector so I can access them in gdb?

For a given type T, you should be able to explicitly instantiate entire vector for that T, by requesting it, e.g.:

template class std::vector<double>;
like image 95
Employed Russian Avatar answered Oct 23 '22 03:10

Employed Russian


Try print by inner member of the vector.

print *(x._M_impl._M_start+0)

Here 0 is the index of data you want to inspect.

Inspired from this answer.

like image 38
phil Avatar answered Oct 23 '22 03:10

phil


Alternately, you coud use the GDB extension below, which will poke at the std::vector fields of GNU libstdc++ and thus works regardless of whether operator[] is instantiated.

Load with:

(gdb) guile (load "the-file.scm")

This creates a new vref command:

(gdb) vref my_vector 0

Code (requires GDB built with Guile support):

(use-modules (gdb)
             (ice-9 match))

(define (std::vector-ref vector index)
  (let* ((impl  (value-field vector "_M_impl"))
         (start (value-field impl "_M_start")))
    (value-subscript start index)))

(define %vector-ref-command
  (make-command "vref"
                #:command-class COMMAND_OBSCURE
                #:doc "Access an element of an std::vector."
                #:invoke
                (lambda (self args tty?)
                  (match (string-tokenize args)
                    ((variable index)
                     (let* ((value (std::vector-ref (parse-and-eval variable)
                                                   (string->number index)))
                            (index (history-append! value)))
                       (format #t "$~a = ~a~%"
                               index (value-print value)))))
                  #t)))

(register-command! %vector-ref-command)
like image 3
civodul Avatar answered Oct 23 '22 04:10

civodul