2010-06-12 2 views
5

Моя программа, которая делает то же самое каждый раз, когда она запускается (перемещает точечный спрайт на расстояние), случайным образом прерывается с текстом на терминале «Незаконная инструкция». Мой googling обнаружил, что люди сталкиваются с этим при написании сборки, что имеет смысл, потому что сборка вызывает эти ошибки.Нелегальная инструкция при программировании на C++ в Linux

Но почему g ++ генерирует незаконную инструкцию, подобную этой? Это не то, что я компилирую для Windows, а затем работает в Linux (что даже тогда, пока оба находятся на x86, AFAIK не должен вызывать нелегальную инструкцию). Я напишу основной файл ниже.

Я не могу достоверно воспроизвести ошибку. Хотя, если я делаю случайные изменения (добавьте пробел здесь, измените константу там), которые заставят перекомпилировать, я могу получить двоичный файл, который будет работать с помощью Illegal Instruction каждый раз, когда он будет запущен, пока я не попытаюсь установить точку останова, что делает незаконное обучение «исчезает». :(

#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

Я предлагаю заменить неисправные модули памяти. – avakar

+3

Я бы предложил заменить неисправного автора комментария. –

+2

Запустите свой код под gdb, а затем, когда вы получите исключение, выполните обратную трассировку (bt). –

ответ

17

компилятор не генерирует нелегальные исключения, с 99,99% вероятностью. Почти наверняка, что происходит в том, что у вас есть ошибка в программе, которая вызывает его либо) перезаписать части вашего исполняемого кода с данными мусора или b) использовать указатель на функцию, указывающий на мусор. Попробуйте запустить программу под valgrind для диагностики проблемы - http://valgrind.org/.

+2

Вариант (b), который следует соблюдать в C++, вызывает виртуальную функцию на объекте, который каким-то образом был перезаписан. –

+2

Я бы не сказал «вероятность 99,99%». Довольно легко заставить компилятор исправить незаконные инструкции, просто лежите о своем процессоре. Если вы сообщите компилятору, что все в порядке, чтобы использовать инструкции AVX2, и ваш CPU на самом деле не имеет их, выполнение первой инструкции AVX2 остановит вашу программу с помощью этой «Нелегальной инструкции», – MSalters

0

Ошибка нелегальной инструкции также может быть признаком неисправного драйвера видеокарты или несоответствующим аппаратным средствам. Используйте lspci | grep VGA, чтобы подтвердить, что на самом деле находится ваше оборудование. Затем попробуйте загрузить самый последний драйвер для вашей аппаратной модели &.

Существует также известная ошибка при запуске кода изнутри NetBeans 6.8 на многоядерной 64-разрядной машине. Код аварийно завершает работу с нелегальной инструкцией, основанной на условиях гонки в профилировщике. Процент сбоев варьируется от 1% или 5% для некоторого кода, 30% или 50%, до примерно 95% +, в зависимости от того, какие библиотеки загружаются. Похоже, что код графики и потоков увеличивает это, но вы можете увидеть его с помощью тривиального Hello World main. Если вы получаете 1% -ный крушение, вы, вероятно, раньше этого не заметили. Решение: запустите исполняемый файл прямо с терминала, если сможете.

Смежные вопросы