2010-06-12 11 views
5

Il mio programma, che fa esattamente la stessa cosa ogni volta che viene eseguito (sposta un punto sprite in lontananza) fallirà casualmente con il testo sul terminale "Istruzione non valida". Il mio google ha trovato persone che incontrano questo quando scrivono assemblaggi che hanno un senso perché l'assemblaggio genera questo tipo di errori.Istruzione non valida durante la programmazione di C++ su Linux

Ma perché g ++ sta generando un'istruzione illegale come questa? Non è che sto compilando per Windows e poi sto girando su Linux (che anche allora, finché entrambi sono su x86, AFAIK non dovrebbe causare un'Istruzione illegale). Pubblicherò il file principale qui sotto.

Non riesco a riprodurre correttamente l'errore. Anche se, se apporto cambiamenti casuali (aggiungo uno spazio qui, cambio una costante lì) che forza una ricompilazione, posso ottenere un binario che fallirà con l'istruzione non valida ogni volta che viene eseguito, finché non provo a impostare un punto di interruzione, il che rende istruzione illegale "dissapear". :(

#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

Suggerirei di sostituire i moduli di memoria difettosi. – avakar

+3

Suggerirei di sostituire l'autore del commento difettoso. –

+2

Esegui il tuo codice in gdb e poi quando ottieni l'eccezione fai un backtrace (bt). –

risposta

17

Il compilatore non genera eccezioni illegali, con il 99,99% di probabilità. Quasi certamente quello che sta succedendo è che avete un bug nel programma che sta causando a uno a) sovrascrivere parti del codice eseguibile con dati spazzatura o b) usa un puntatore a funzione che punta nella spazzatura. Prova a eseguire il tuo programma sotto valgrind per diagnosticare il problema - http://valgrind.org/.

+2

Una variante di (b) a cui prestare attenzione in C++ chiama una funzione virtuale su un oggetto che è stato sovrascritto in qualche modo. –

+2

Non direi "probabilità del 99,99%". È abbastanza facile far compilare un compilatore da istruzioni illegali, mentire sulla tua CPU. Se dici al compilatore che è OK usare le istruzioni AVX2 e la tua CPU in realtà non ce l'ha, l'esecuzione della prima istruzione AVX2 fermerà il tuo programma con quella "Istruzione illegale" – MSalters

0

Il bug dell'istruzione non valida può anche essere un sintomo di un driver della scheda grafica difettoso o di uno non corrispondente all'hardware. Usa lspci | grep VGA per confermare il tuo hardware in realtà. Quindi prova a scaricare il più recente driver & per il tuo modello hardware.

C'è anche un bug noto quando si esegue il codice da NetBeans 6.8 su una macchina multi-core a 64-bit. Il codice si blocca stocasticamente con Istruzione non valida in base alle condizioni di gara nel profiler. La percentuale di arresti anomali varia dall'1% al 5% per alcuni codici, il 30% o il 50%, fino a circa il 95% +, a seconda delle librerie caricate. Il codice di grafica e thread sembra aumentare, ma puoi vederlo con un banale Hello World main. Se ottieni un tasso di arresto dell'1%, probabilmente non l'hai notato prima. Soluzione: esegui l'eseguibile direttamente da un terminale, se puoi.

Problemi correlati