Illegal instruction与march编译选项

本文探讨了Illegalinstruction(coredumped)错误的原因及解决方法。通常情况下,这种错误是由于进程尝试执行不可识别的指令引起的。文章重点介绍了两种常见情况:一是数据被错误地写入代码段;二是编译时指定的CPU架构与实际运行的机器不匹配。

前几天在运行一个模型训练工具的时候,发现了一个Illegal instruction (core dumped)的错误。话说这种错误以前没怎么见过。这是一个开源的项目,我是运行的从同事那边拿来的工具,就会这样,但是我自己下载源码重新编译后运行一切正常。于是就查了查这个Illegal instruction是怎么回事,毕竟这货不比segmentfault常见。

查阅显示,illegal instruction,即SIGILL, 是POSIX标准中提供的一类错误。 从名字上看,SIGILL是启动的某个进程中的某一句不能被CPU识别成正确的指令。 此类错误是由操作系统发送给进程的,在进程试图执行一些形式错误、未知或者特权指令时操作系统会使用SIGILL信号终止程序。果然如名字一样,非法指令。那么,在什么情况下会出现这种错误呢,一般来说,有两种可能,一是将数据错误地写进了代码段,导致将本不是指令的数据当成指令去执行;第二种可能是编译时指定的CPU架构与实际运行的机器不一致。这里主要讲讲第二种。

由于CPU架构的演进,CPU指令集一直在不断地拓展,SSE、SSE2、SSE3、SSE42、AVX、AVX2等。不同的CPU能支持的指令集是不一样的,如果编译程序时指定了使用新的CPU架构进行编译,则该程序在老的CPU上运行时,其指令就不能被执行,从而引发Illegal instruction错误。查阅gcc资料,gcc是提供了一个march编译选项来指定所使用的CPU架构的。如果不清楚自己的CPU类型,可以使用gcc -c -Q -march=native --help=target | grep march来查看:

music@ds01:~$ gcc -c -Q -march=native --help=target | grep march
  -march=                             corei7-avx
music@ds01:~$

如果在编译时指定了-march参数,gcc将不会再用兼容的指令去编译,而是根据指定的CPU架构,采用其特定的指令集如AVX去生成二进制代码。因此,当你确定所编译的程序只会在特定的环境中运行时,可以使用-march参数来指定CPU架构,这样编译器就可以根据你的CPU架构进行指令上的优化,而这个指定带来的结果就是,如果你将程序放在其他机器上运行,有可能得到Illegal instruction的运行错误。

 

转载于:https://www.cnblogs.com/yutongqing/p/6823385.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值