4

这是我的课程的一个极其简化的版本:

Class MyClass {
public:
    int sizeDesired;
};

MyClass在 main 中创建一个实例向量:

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,我该怎么做?


当我在将所有实例推送到主要实例后中断时MyClassstd::vector<MyClass>我会这样做

(gdb) watch myvec[0].sizeDesired

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


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

4

1 回答 1

3

我在 gdb 中没有做太多的 C++ 调试,所以这些可能都是众所周知的问题。

您的观察点的问题似乎是由 gdb 无法实际执行某些方法引起的,例如 [] 运算符或 at() 方法。你可以通过给出 print 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

于 2013-06-14T08:20:33.400 回答