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, есть ли альтернативный инструмент, который можно использовать?

4

Решение

Я не делал много отладки 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: ((Интермедиат) 0x40508c)

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

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]