调试一个大的双数组

时间:2010-01-12 13:23:31

标签: c++ c debugging

我正在使用一个C ++库,它提供了一个对象,为了简单起见,它或多或少是这样的:

class ExampleSO {
    public double* narray;
};

我有一个ExampleSO的实例,其narray大约为200.其他方法ExampleSO::method()使用此数组执行许多算术函数并将其分配给不同的数组元素:

ExampleSO::method() {
     // a lot of operations
     narray[50] = narray[1] * narray[2] / narray[40];
     // and so on

此代码由另一个程序生成,它使用一堆定义来处理数组元素,因此代码如下所示:

#define A narray[0]
#define X narray[1]
#define Y narray[2]
// ...
#define Z narray[40]
// ....
#define U narray[50]
// ... more, until narray[199]
ExampleSO::method() {
     // a lot of operations
     U = X * Y / Z;
     // and so on
}

我的问题是,最终一些数组元素是NaN,我正在尝试调试代码以查看原因。我已经发现了其中的一些,主要是由零除,其他通过非常小的数字(在0和+/- 0.1之间的小数)引起。

由于我对gdb魔法知之甚少,我设法通过display *(this->narray) @ 200看到数组元素,但是这个数组非常大,因此不可读。

所以调试这段代码已经变成了一个简单的任务,因为#defines隐藏了元素的位置,数组太大了,因为很多元素变成了NaN,我迷失了

我的问题是:您有什么想法/建议来帮助我调试此代码?当第一个数组元素变成NaN时,条件断点可能有用吗?我怎么能用这样的结构呢?

谢谢!

3 个答案:

答案 0 :(得分:4)

  1. 重写它。你所描述的结构是无法描述的。
  2. 编写一个python脚本将#defines转换为gdb变量别名,以便您可以象征性地引用它们。
  3. 在gdb中使用数组语法:p narray[12]
  4. 添加一些调试助手函数并从调试器中调用它们:p printMyFavoriteValues(narray)
  5. 了解如何启用信令NaN。 Windows与Mac与Linux不同。

  6. #ifdef DARWIN
        _mm_setcsr( _MM_MASK_MASK &~
                  (_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO) );
    #else
        feenableexcept(FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID);
    #endif
    

答案 1 :(得分:1)

关于定义,您可以通过预处理器运行文件,然后编译和调试预处理文件本身。

X,Y,Z宏将以这种方式解析,你会看到实际的索引。如何调用预处理器本身取决于您的编译器。对于gcc,它是cpp命令Documentation

关于找出分配NaN的时间,应该有一个编译器开关,当程序发生这种情况时会使程序抛出异常。

答案 2 :(得分:0)

如果需要调试宏调用生成的大量代码而无法重构删除宏,则可以选择暂时预处理文件,复制宏生成的代码并将其粘贴到宏上调用。然后,您就可以编译已经预处理的代码并正确调试。当你完成后只需恢复代码。