GDB Не удалось найти оператор []

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

var1 = 1;
var2 = 2;

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

Когда я отлаживаю этот код в gdb и пытаюсь вывести x[0] или *x[0], я получаю: Не удалось найти оператор []. Теперь, если я включу эту строку после push_back:

x[0] = &var1;

Я могу получить доступ к любым конкретным элементам в GDB. То же самое происходит с другими членами, такими как front(), at() и т. Д. Насколько я понимаю, компилятор / компоновщик включает только функции-члены, присутствующие в исходном коде, и те, которые я могу использовать в gdb. Есть ли способ включить каждую функцию-член std::vector, чтобы я мог получить к ним доступ в GDB?

3 ответа

Решение

Насколько я понимаю, компилятор / компоновщик включает только функции-члены, присутствующие в исходном коде, и это те, которые я могу использовать в GDB.

Ваше понимание неверно / неполно.

std::vector это шаблон класса. Без явного создания экземпляра компилятор обязан создавать экземпляры только вызываемых методов (обычно это подмножество методов, присутствующих в источнике).

Есть ли способ включить каждую функцию-член std::vector, чтобы я мог получить к ним доступ в GDB?

Для данного типа T, вы должны быть в состоянии явно создать экземпляр всего вектора для этого T, запрашивая его, например:

template class std::vector<double>;

Попробуйте распечатать по внутреннему члену вектора.

print *(x._M_impl._M_start+0)

Вот 0 это индекс данных, которые вы хотите проверить.

Вдохновлен этим ответом.

Кроме того, вы можете использовать расширение GDB ниже, которое будет тыкать в std::vector поля GNU libstdC++ и, таким образом, работает независимо от того, operator[] создается экземпляр.

Загрузить с помощью:

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

Это создает новый vref команда:

(gdb) vref my_vector 0

Код (требуется GDB, созданный с поддержкой Guile):

(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)

Функции.at(), .begin() у меня почему-то работают. Возможно, у меня установлен флаг -g.

Другие вопросы по тегам