这是我班级的极简化版本:
Class MyClass {
public:
int sizeDesired;
};
我正在main中创建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
的所有实例推送到main中的std::vector<MyClass>
后我休息时,我会这样做
(gdb) watch myvec[0].sizeDesired
但GDB只是挂起。它不显示新的命令提示符(即,它不会在后续行显示(gdb)
...只是一个空白行,似乎没有发生任何事情。)
我对非基于GDB的解决方案持开放态度。如果在GDB中无法进行这种类型的检查/监控,是否有可以使用的替代工具?
答案 0 :(得分:2)
我没有在gdb中做很多C ++调试,所以这些可能都是众所周知的问题。
你的观察点的问题似乎是由于gdb无法实际执行某些方法,如[] operator或at()方法。你可以通过给出print myvec.at(0)来试试这个。看起来这个测试在watchpoint代码中缺失,它冻结了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解决的。