2010-06-12 310 views
5

我的程序在每次运行时都会执行完全相同的操作(将点精灵移动到距离内),并随终端'非法指令'上的文本随机失败。在编写程序集时,我的谷歌搜索发现人们遇到这种情况,因为程序集会抛出这些错误。在Linux上编程C++时出现非法指令

但为什么g ++会生成这样的非法指令?这不像我为Windows编译然后在Linux上运行(即使这样,只要两者都在x86上,AFAIK不应该导致非法指令)。我会在下面发布主文件。

我无法可靠地重现错误。虽然,如果我进行随机更改(在这里添加一个空格,在那里改变一个常量),强制重新编译,我可以得到一个二进制文件,每当它运行时都会失败,直到我尝试设置一个断点,这使得非法指示“消失”。 :(

#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 2010-06-12 20:11:02

+3

我会建议替换错误的评论作者。 – 2010-06-12 20:20:12

+2

在gdb下运行你的代码,然后当你得到异常时执行回溯(bt)。 – 2010-06-12 20:39:34

回答

17

编译器不产生合法例外,有99.99%的概率。几乎可以肯定发生了什么事是,你必须在你的程序,这是造成它到任何一个)覆盖的可执行代码部分中的错误与垃圾数据,或b)使用指向垃圾的函数指针。尝试运行valgrind下的程序来诊断问题 - http://valgrind.org/

+2

在C++中注意(b)的一个变体是调用某个已被覆盖的某个对象的虚函数。 – 2010-06-12 20:22:40

+2

我不会说“99.99%的概率”。让编译器发出非法指令很容易,只是谎报你的CPU。如果你告诉编译器可以使用AVX2指令,而你的CPU实际上并没有这些指令,那么执行第一条AVX2指令将会停止你的程序的“非法指令” – MSalters 2016-04-13 11:16:01

0

非法指令错误也可能是故障显卡驱动程序的症状,或者是与硬件不匹配的错误。使用lspci | grep VGA来确认您的硬件实际是什么。然后尝试为您的硬件模型下载最新的驱动程序&。

在多核64位机器上从NetBeans 6.8内部运行代码时也存在一个已知的错误。该代码根据Profiler中的竞争条件随机地使用非法指令进行崩溃。崩溃的百分比从一些代码的1%或5%,30%或50%,高达95%左右,取决于哪些库正在加载。图形和线程代码似乎增加了这一点,但你可以看到它与一个简单的Hello World主。如果你有1%的崩溃率,你可能以前没有注意到它。解决方案:如果可以的话,直接从终端运行可执行文件。