2010-06-12 16 views
5

Mi programa, que hace exactamente lo mismo cada vez que se ejecuta (se mueve un sprite punto en la distancia) fallará al azar con el texto en el terminal 'instrucción ilegal'. Mi Google ha encontrado personas que se encuentran con esto cuando escriben ensamblado, lo cual tiene sentido porque el ensamblado arroja ese tipo de errores.instrucción ilegal Cuando programación C++ en Linux

Pero ¿por qué g ++ estar generando una instrucción ilegal de esta manera? No es como si estuviera compilando para Windows y ejecutando en Linux (que incluso entonces, siempre y cuando ambos estén en x86, no debería AFAIK causar una instrucción ilegal). Publicaré el archivo principal a continuación.

No puedo reproducir de forma fiable el error. Aunque, si realizo cambios aleatorios (agregue un espacio aquí, cambie una constante allí) que fuerce una recompilación, puedo obtener un binario que fallará con la instrucción ilegal cada vez que se ejecute, hasta que intente establecer un punto de interrupción, lo que hace que el instrucción ilegal 'desaparece'. :(

#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

Yo sugeriría cambiar los módulos de memoria defectuosos. – avakar

+3

Sugeriría reemplazar el autor del comentario defectuoso. –

+2

Ejecute su código en gdb y luego cuando obtenga la excepción haga una traza inversa (bt). –

Respuesta

17

El compilador no genera excepciones ilegales, con el 99,99% de probabilidad. Es casi seguro que lo que está sucediendo es que usted tiene un error en su programa que está provocando que sea a) sobrescribir partes de su código ejecutable con datos basura, o b) use un puntero a la función que apunte a la basura. Intente ejecutar su programa en valgrind para diagnosticar el problema - http://valgrind.org/.

+2

Una variante de (b) para tener cuidado en C++ es llamar a una función virtual en un objeto que ha sido sobrescrito de alguna manera. –

+2

No diría "99.99% de probabilidad". Es bastante fácil hacer que un compilador emita instrucciones ilegales, solo mienta acerca de su CPU. Si le dices al compilador que está bien usar las instrucciones AVX2, y tu CPU no las tiene en realidad, ejecutar la primera instrucción AVX2 detendrá tu programa con esa "Instrucción Ilegal" – MSalters

0

El error de instrucción ilegal también puede ser un síntoma de un controlador defectuoso, o uno que es coincidente con el hardware. Use lspci | grep VGA para confirmar cuál es realmente su hardware. A continuación, intente descargar el último controlador más grande & para su modelo de hardware.

También hay un fallo conocido cuando se ejecuta el código desde el interior de NetBeans 6.8 en una máquina multi-core de 64 bits. El código se bloquea de forma estocástica con la instrucción ilegal según las condiciones de carrera en el generador de perfiles. El porcentaje de bloqueos varía de 1% o 5% para algún código, 30% o 50%, hasta aproximadamente 95%, según las bibliotecas que se carguen. El código de gráficos e hilos parece aumentar esto, pero puedes verlo con un trivial Hello World principal. Si obtiene una tasa de colisión del 1%, es probable que no lo haya notado antes. Solución: ejecuta el ejecutable directamente desde una terminal, si puedes.