在Linux上编程C ++时的非法指令

时间:2010-06-12 20:07:10

标签: c++ gcc g++

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

但为什么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();} 
}

3 个答案:

答案 0 :(得分:17)

编译器不会生成非法异常,概率为99.99%。几乎可以肯定的是,你的程序中有一个错误导致它a)用垃圾数据覆盖部分可执行代码,或b)使用指向垃圾的函数指针。尝试在valgrind下运行程序来诊断问题 - http://valgrind.org/

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

您的驱动程序很可能是Mesa软件渲染或错误的图形卡驱动程序。 Mesa有时会使用特殊的指令集,例如AVX,AVX2等。

您的 glEnable(GL_POINT_SPRITE_ARB);代码可能正在从Mesa激活不适合您的CPU的部件。

我知道该职位很旧,但将来可能会帮助其他人。