2010-06-12 22 views
5

Programım her seferinde aynı şeyi yapar (bir nokta hareketini mesafeye taşır), 'Yasa Dışı Talimat' terminalindeki metinle rasgele başarısız olur. Amacım, montajı yazarken insanların bu tür karşılaşmalarla karşılaştıklarını fark etti.Linux'ta C++ Programlamaya Yönelik Yasa Dışı Talimat

Fakat neden g ++ böyle yasadışı bir talimat üretiyor? Windows için derlediğimden daha sonra Linux üzerinde çalışmam gibi değil (ki o zaman bile, her ikisi de x86'da olduğu sürece AFAIK'ın Yasa Dışı Talimat vermemesi gerekir). Aşağıdaki ana dosyayı göndereceğim.

Hatayı güvenilir şekilde yeniden oluşturamıyorum. Rastgele değişiklikler yaparsam (burada bir boşluk ekleyin, burada bir değişmez) bir derlemeyi zorladığım halde, her seferinde Yasa Dışı Talimatla başarısız olan bir ikili alabilirim. yasadışı talimat 'kaybolur'. :(

#include <stdio.h> 
#include <stdlib.h> 
#include <GL/gl.h> 
#include <GL/glu.h> 

#include <SDL/SDL.h> 

#include "Screen.h" //Simple SDL wrapper 
#include "Textures.h" //Simple OpenGL texture wrapper 
#include "PointSprites.h" //Simple point sprites wrapper 


double counter = 0; 
/* Here goes our drawing code */ 
int drawGLScene() 
{ 
    /* These are to calculate our fps */ 
    static GLint T0  = 0; 
    static GLint Frames = 0; 

    /* Move Left 1.5 Units And Into The Screen 6.0 */ 
    glLoadIdentity(); 
glTranslatef(0.0f, 0.0f, -6); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 

glEnable(GL_POINT_SPRITE_ARB); 
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); 
    glBegin(GL_POINTS); /* Drawing Using Triangles */ 
glVertex3d(0.0,0.0, 0); 
glVertex3d(1.0,0.0, 0); 
glVertex3d(1.0,1.0, counter); 
glVertex3d(0.0,1.0, 0); 
    glEnd();       /* Finished Drawing The Triangle */ 

    /* Move Right 3 Units */ 


    /* Draw it to the screen */ 

    SDL_GL_SwapBuffers(); 
    /* Gather our frames per second */ 
    Frames++; 
    { 
GLint t = SDL_GetTicks(); 
if (t - T0 >= 50) { 
    GLfloat seconds = (t - T0)/1000.0; 
    GLfloat fps = Frames/seconds; 
    printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps); 
    T0 = t; 
    Frames = 0; 
    counter -= .1; 
} 
    } 

    return 1; 
} 

GLuint objectID; 
int main(int argc, char **argv) 
{ 
Screen screen; 
screen.init(); 
screen.resize(800,600); 


LoadBMP("./dist/Debug/GNU-Linux-x86/particle.bmp"); 
InitPointSprites(); 


while(true){drawGLScene();} 
} 
+1

Hatalı bellek modüllerini değiştirmenizi öneririm. – avakar

+3

Hatalı yorum yazarını değiştirmeyi öneririm. –

+2

Kodunuzu gdb altında çalıştırın ve sonra istisna yaptığınızda bir backtrace (bt) yapın. –

cevap

17

derleyici% 99.99 olasılıkla, yasadışı istisnalar yaratmamaktadır. Neredeyse kesinlikle neyi oluyor bunu ya a) çalıştırılabilir kod parçaları üzerine neden olan programınızda bir hata olması çöp verisi ile veya b) çöpü işaret eden bir işlev işaretçisi kullanın. Sorunu teşhis etmek için programınızı valgrind altında çalıştırmayı deneyin - http://valgrind.org/.

+2

C++ 'da dikkat edilmesi gereken bir (b) çeşidi, bir şekilde üzerine yazılan bir nesnede sanal bir işlev çağırıyor. –

+2

"% 99.99 olasılık" demem. Bir derleyicinin yasadışı talimatları yayması oldukça kolaydır, sadece CPU'nuz hakkında yalan söyleyin. Derleyiciye söylerseniz AVX2 komutlarını kullanmanız yeterli değildir ve CPU'nuzun gerçekte bunlara sahip olmaması, ilk AVX2 komutunun yürütülmesi programınızı "Yasa Dışı Talimat" ile durdurur. – MSalters

0

Yasa Dışı Talimat hatası, hatalı bir grafik kartı sürücüsünün veya donanımla eşleşmeyen bir sürücünün belirtisi olabilir. Donanımınızın gerçekte ne olduğunu doğrulamak için lspci | grep VGA kullanın. Ardından, donanım modeliniz için en son & en büyük sürücüyü indirmeyi deneyin. Çok çekirdekli 64-bit bir makinede NetBeans 6.8'in içinden kod çalıştırırken bilinen bir hata da vardır. Kod, profilerdeki yarış koşullarına dayalı olarak Yasa Dışı Talimatlarla stokastik olarak çöküyor. Kazaların yüzdesi, hangi kütüphanelerin yüklendiğine bağlı olarak, bazı kodlar için% 1 veya% 5,% 30 veya% 50,% 95'e kadar değişmektedir. Grafik ve konu kodu bunu arttırıyor gibi görünüyor, ancak bunu önemsiz bir Merhaba Dünya ana ile görebiliyorsunuz. % 1'lik bir çarpışma oranı alırsanız, muhtemelen daha önce farketmediniz. Çözüm: Yapabilirseniz, doğrudan bir terminalden yürütülebilir dosyayı çalıştırın.

İlgili konular