Вот чрезвычайно упрощенная версия моего класса:
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, есть ли альтернативный инструмент, который можно использовать?
Я не делал много отладки 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.
Других решений пока нет …