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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3029943/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 11:51:22  来源:igfitidea点击:

Illegal Instruction When Programming C++ on Linux

c++gccg++

提问by user327406

My program, which does exactly the same thing every time it runs (moves a point sprite into the distance) will randomly fail with the text on the terminal 'Illegal Instruction'. My googling has found people encountering this when writing assembly which makes sense because assembly throws those kinds of errors.

我的程序每次运行时都做完全相同的事情(将一个点精灵移到远处)将随机失败并在终端“非法指令”上显示文本。我的谷歌搜索发现人们在编写程序集时遇到这种情况,这是有道理的,因为程序集会抛出这些类型的错误。

But why would g++ be generating an illegal instruction like this? It's not like I'm compiling for Windows then running on Linux (which even then, as long as both are on x86 shouldn't AFAIK cause an Illegal Instruction). I'll post the main file below.

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

I can't reliably reproduce the error. Although, if I make random changes (add a space here, change a constant there) that force a recompile I can get a binary which will fail with Illegal Instruction every time it is run, until I try setting a break point, which makes the illegal instruction 'dissapear'. :(

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

#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();} 
}

回答by JSB????

The compiler isn't generating illegal exceptions, with 99.99% probability. Almost certainly what's happening is that you have a bug in your program which is causing it to either a) overwrite parts of your executable code with garbage data, or b) use a function pointer that points into garbage. Try running your program under valgrind to diagnose the problem - http://valgrind.org/.

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

回答by DragonLord

The Illegal Instruction bug can also be a symptom of a faulty graphics card driver, or one that's mismatched to the hardware. Use lspci | grep VGAto confirm what your hardware actually is. Then try downloading the latest & greatest driver for your hardware model.

非法指令错误也可能是显卡驱动程序故障或与硬件不匹配的症状。使用lspci | grep VGA要确认你的硬件实际上是。然后尝试为您的硬件型号下载最新和最好的驱动程序。

There is also a known bug when running code from inside NetBeans 6.8 on a multi-core 64-bit machine. The code crashes stochastically with Illegal Instruction based on race conditions in the profiler. Per cent of crashes varies from 1% or 5% for some code, 30% or 50%, up to around 95%+, depending on which libraries are being loaded. Graphics and threads code seems to increase this, but you can see it with a trivial Hello World main. If you get a 1% crash rate, you probably haven't noticed it before. Solution: run the executable straight from a terminal, if you can.

在多核 64 位机器上从 NetBeans 6.8 内部运行代码时,还有一个已知错误。代码会根据分析器中的竞争条件随机出现非法指令崩溃。崩溃的百分比从某些代码的 1% 或 5%、30% 或 50% 到大约 95% 以上不等,具体取决于正在加载的库。图形和线程代码似乎增加了这一点,但您可以通过一个简单的 Hello World 主程序看到它。如果您获得 1% 的崩溃率,您可能以前没有注意到。解决方案:如果可以,直接从终端运行可执行文件。