gdb Could not find operator[]

2019-02-06 04:19发布

问题:

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. 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?

回答1:

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>;


回答2:

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.



回答3:

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)


标签: c++ vector gdb