Mon programme, qui fait exactement la même chose à chaque fois qu'il s'exécute (déplacer un sprite ponctuel au loin), échoue de manière aléatoire avec le texte suivant sur le terminal : "Instruction illégale". En cherchant sur Google, j'ai trouvé des gens qui rencontrent ce problème en écrivant de l'assembleur, ce qui est logique puisque l'assembleur génère ce genre d'erreurs.
Mais pourquoi g++ générerait-il une instruction illégale comme celle-ci ? Ce n'est pas comme si je compilais pour Windows et que j'exécutais ensuite sous Linux (ce qui, même dans ce cas, tant que les deux sont sur x86, ne devrait pas AFAIK causer une instruction illégale). Je vais poster le fichier principal ci-dessous.
Je ne peux pas reproduire l'erreur de manière fiable. Cependant, si je fais des changements aléatoires (ajouter un espace ici, changer une constante là) qui forcent une recompilation, je peux obtenir un binaire qui échouera avec une instruction illégale à chaque exécution, jusqu'à ce que j'essaie de mettre un point d'arrêt, ce qui fait "disparaître" l'instruction illégale.
#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 votes
Je suggère de remplacer les modules de mémoire défectueux.
6 votes
Je suggère de remplacer l'auteur du commentaire défectueux.
2 votes
Exécutez votre code sous gdb et lorsque vous obtenez l'exception, faites un backtrace (bt).
0 votes
Si le terme "x86" est simple, il existe en fait des dizaines de variantes, car Intel et AMD n'ont cessé d'ajouter de nouvelles instructions (il s'agit d'une ISA CISC, après tout). En ignorant les extensions évidentes comme SSE et MMX, il existe également des instructions plus basiques telles que
CMOV
(déplacement conditionnel) qui n'étaient pas présents sur le 80386 original (le premier CPU x86-32).