GDB наблюдает за членом класса в векторе экземпляров

Вот чрезвычайно упрощенная версия моего класса:

Class MyClass {
public:
    int sizeDesired;
};

Я создаю вектор MyClass экземпляры в основном:

int main(int argc, char **argv) {

    std::vector<MyClass> myvec;

    for(int i=0; i<10; ++i)
        myvec.push_back(MyClass());

    for(int i=0; i<myvec.size(); ++i)
        doWork(myvec[i]);

    return 0;
}

Есть некоторая ошибка повреждения памяти (я думаю), которая вызывает сбой моей программы. Я заметил, что значение MyClass::sizeDesired это мусор, когда программа падает. Итак, я хочу установить точку наблюдения на каждом MyClass:sizeDesired член, так что я могу точно видеть, когда значения любого из этих членов изменяется.

Используя GDB, как я могу это сделать?


Когда я ломаюсь после нажатия всех экземпляров MyClass на std::vector<MyClass> в основном я тогда делаю

(gdb) watch myvec[0].sizeDesired

но GDB просто виснет. Он не отображает новую командную строку (то есть не показывает (gdb) на следующей строке... просто пустая строка и ничего не происходит).


Я открыт для решений, не основанных на GDB. Если этот тип проверки / мониторинга невозможен в GDB, есть ли альтернативный инструмент, который можно использовать?

1 ответ

Решение

Я не делал много отладки C++ в GDB, так что это, вероятно, все хорошо известные проблемы.

Кажется, проблема с вашей точкой наблюдения вызвана неспособностью GDB фактически выполнить некоторые методы, такие как оператор [] или метод at(). Вы можете попробовать это, просто напечатав myvec.at (0). Похоже, что этот тест отсутствует в коде наблюдения и замораживает GDB. (Вероятно, это известная ошибка GDB, но я проверю.)

Теперь для обхода. Вы можете получить доступ к n-му элементу вектора, используя:

(MyClass*)(myvec._M_impl._M_start+n)

Для sizeDesired это будет:

(((MyClass*)(myvec._M_impl._M_start+n))->sizeDesired)

Добавление точки наблюдения к этому выражению все еще останавливает GDB по некоторым причинам. Но печать работает, так что если вы делаете что-то вроде:

print &(((MyClass*)(myvec._M_impl._M_start+3))->sizeDesired)

Вы получите указатель на поле, которое хотите посмотреть. Примерно так будет напечатано: $1 = (int *) 0x40508c Теперь выпустите:

watch *((int*)0x40508c)
continue

Аппаратный доступ (чтение / запись), точка наблюдения 3: ((int) 0x40508c)...

Кстати: идеи о том, как печатать стандартные контейнеры, были найдены на сайте http://sourceware.org/ml/gdb/2008-02/msg00064/stl-views.gdb.

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