c – GDB在实例向量中观察类成员

这是我班级的极简化版本:

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的所有实例推送到std :: vector< MyClass>之后我休息时在主要的,我然后做

(gdb) watch myvec[0].sizeDesired

但GDB只是挂起了.它不会显示新的命令提示符(即,它不会在后续行显示(gdb)…只是一个空白行,似乎没有发生任何事情).

我对非基于GDB的解决方案持开放态度.如果在GDB中无法进行此类检查/监控,是否有可以使用的替代工具?

最佳答案 我没有在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开始的.

点赞