2011-07-21 9 views
1

私は一般的にC++とopenmpでかなり新しいです。私は、少なくとも私には奇妙な状況でセグメンテーション違反の原因となっているプログラムの一部を持っています。openmpのセグメント違反 - 奇妙な動作

g ++コンパイラを使用する場合は発生しませんが、intelコンパイラでは発生しませんが、シリアルにはフォルトはありません。

別のシステム(大学のhpc、intelコンパイラ)でコンパイルするとsegfaultもありませんが、私のPCではそうです。

3つの特定のcoutステートメントが存在する場合は、セグメンテーションも行われませんが、いずれか1つがコメントアウトされている場合は、segfaultが発生します。 (これは私が奇妙な発見です)

私はintelデバッガ(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; 
    } 
} 

}

3上の行が私が追加したものであり、私が行ったときにプログラムが動作することがわかりました。例えば第三coutのラインで

私はそれを変更した場合、:

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

私はセグメンテーション違反を取得し、または私はそれを変更した場合:

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

、私はまた、セグメンテーション違反を得ます。

読んでいただきありがとうございます。

答えて

2

は、すでに述べたように、あなたが検出するために、Valgrindのを使用しようとすることができ、前の回答で述べた http://software.intel.com/sites/products/documentation/hpc/composerxe/en-us/cpp/lin/optaps/common/optaps_par_var.htm

  • 、スタックのサイズを大きくあなたの記憶は壊れています。ただ、「-g -O0」を使用してバイナリをコンパイルしてから実行します。

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

    運がよければ、あなたがメモリ違反が発生したソースコードに正確な行と列を取得します。

    「printf」文がいくつか追加されたときにsegfaultが消えるというのは、実際には奇妙なことではありません。これらのステートメントを追加すると、プログラムが所有するメモリの部分が変更されます。何らかの理由でメモリの許容部分の間違った場所に書き込んでいる場合、segfaultは発生しません。

    あなたは、トピックのより広範な説明については(セクション「デバッグ技術/範囲外」)は、このPDFファイルを参照することができ

    :私は

    :-)助けてきた

    Summer School of Parallel Computing

    ・ホープ

  • 1
    • トライトライvalgrindの

    • トライデバッガ

    +0

    ありがとう、私はまた、どのように勘違いがsegfault – CptLightning