2011-07-21 122 views
1

我很新的C++和openmp一般。我有一部分程序在奇怪的情况下导致了分段错误(至少对我来说很陌生)。openmp分段错误 - 奇怪的行为

使用g ++编译器时不会发生这种情况,但可以使用intel编译器,但串行中没有任何错误。

它编译不同系统(大学hpc,英特尔编译器)时也不会出现段错误,但在我的电脑上。

当存在三个特定的cout语句时,它也不会发生段错误,但是如果其中任何一个被注释掉,则会发生段错误。 (这是我觉得奇怪的)

我是新来的使用英特尔调试器(idb),我不知道如何正确地工作。但我还是设法从它那里得到这样的信息:

Program received signal SIGSEGV 
VLMsolver::iterateWake (this=<no value>) at /home/name/prog/src/vlmsolver.cpp:996 
996  moveWakePoints(); 

所以我会出现如下图所示moveWakePoints方法,并指出关键COUT线:

void VLMsolver::moveWakePoints() { 

inFreeWakeStage =true; 
int iw = 0; 
std::vector<double> wV(3); 
std::vector<double> bV(3); 
for (int cl=0;cl<3;++cl) { 
    wV[cl]=0; 
    bV[cl]=0; 
} 

cout<<"thanks for helping"<<endl; 

for (int b = 0;b < sNumberOfBlades;++b) { 
    cout<<"b: "<<b<<endl; 
    #pragma omp parallel for firstprivate(iw,b,bV,wV) 
    for (int i = 0;i< iteration;++i) { 
     iw = iteration -i - 1; 
     for (int j = 0;j<numNodesY;++j) { 
      cout<<"b: "<<b<<"a: "<<"a: "<<endl; 
      double xp = wakes[b].x[iw*numNodesY+j]; 
      double yp = wakes[b].y[iw*numNodesY+j]; 
      double zp = wakes[b].z[iw*numNodesY+j]; 
      if ((sFreeWake ==true && sFreezeAfter == 0) || (sFreeWake==true && iw<((sFreezeAfter*2*M_PI)/(sTimeStep*sRotationRate)) && sRotationRate != 0 ) || (sFreeWake==true && sRotationRate == 0 && iw<((sFreezeAfter*sChord)/(sTimeStep*sFreeStream)))) { 
       if (iteration>1) { 
        getWakeVelocity(xp, yp, zp, wV); 
       } 
       getBladeVelocity(xp, yp, zp, bV); 
      } else { 
       for (int cl=0;cl<3;++cl) { 
        wV[cl]=0; 
        bV[cl]=0; 
       } 
      } 
      if (sRotationRate != 0) { 
       double theta; 
       theta = M_PI/2; 
       double radius = sqrt(pow(yp,2) + pow(zp,2)); 
       wakes[b].yTemp[(iw+1)*numNodesY+j] = cos(theta - sTimeStep*sRotationRate)*radius; 
       wakes[b].zTemp[(iw+1)*numNodesY+j] = sin(theta - sTimeStep*sRotationRate)*radius; 
       wakes[b].xTemp[(iw+1)*numNodesY+j] = xp + sFreeStream*sTimeStep; 
      } else { 
       std::vector<double> fS(3); 
       getFreeStreamVelocity(xp, yp, zp, fS); 
       wakes[b].xTemp[(iw+1)*numNodesY+j] = xp + fS[0] * sTimeStep; 
       wakes[b].yTemp[(iw+1)*numNodesY+j] = yp + fS[1] * sTimeStep; 
       wakes[b].zTemp[(iw+1)*numNodesY+j] = zp + fS[2] * sTimeStep; 
      } 
      wakes[b].xTemp[(iw+1)*numNodesY+j] = wakes[b].xTemp[(iw+1)*numNodesY+j] + (wV[0]+bV[0])*sTimeStep; 
      wakes[b].yTemp[(iw+1)*numNodesY+j] = wakes[b].yTemp[(iw+1)*numNodesY+j] + (wV[1]+bV[1])*sTimeStep; 
      wakes[b].zTemp[(iw+1)*numNodesY+j] = wakes[b].zTemp[(iw+1)*numNodesY+j] + (wV[2]+bV[2])*sTimeStep; 

     } // along the numnodesy 
    } // along the iterations i 
    if (sBladeSymmetry) { 
     break; 
    } 
} 

}

三最上面的cout行是我添加的,并且发现程序在我做的时候工作。

在例如第三COUT行,如果我将其更改为:

cout<<"b: "<<"a: "<<"a: "<<endl; 

我得到的内存设计缺陷,或者如果我将其更改为:

cout<<"b: "<<b<<endl; 

,我也得到了段错误。

感谢您的阅读,我很欣赏任何想法。

回答

2

正如在前面的回答已经说过,你可以尝试使用Valgrind的检测你的内存已损坏。只要编译“-g -O0”你的二进制文件,然后运行:

valgrind --tool=memcheck --leak-check=full <binary> <arguments> 

如果你是幸运的你将得到的源代码已经发生内存冲突确切的行和列。

当添加一些“printf”语句时segfault消失的事实并不奇怪。添加这些语句可以修改程序拥有的内存部分。如果由于任何可能,你在一个允许的内存部分写错了位置,那么段错误就不会发生。

您可以参考这个PDF(节“调试技术/出界”)为主题的更广泛的解释:我一直在帮助:-)

Summer School of Parallel Computing

希望