C 非法指令

Mat*_*hew 0 c x86-64 undefined-behavior illegal-instruction

下面是我写的 ac 程序的打印件,我运行它的演示,最后是关于我的编译器的一些信息。

?  illegalInstructionDebug cat illegal.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void func(int* Z){
    Z[-11] = acos(2);
}

int main(){
    fflush(stdout);
    printf("");
    fflush(stdout);
    int X[3];
    int Z[3];
    for (int n=0;0!=0;);
    func(Z);
}
?  illegalInstructionDebug gcc illegal.c; ./a.out
[1]    28836 illegal hardware instruction  ./a.out
?  illegalInstructionDebug clang --version
Apple clang version 11.0.3 (clang-1103.0.32.62)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
?  illegalInstructionDebug
Run Code Online (Sandbox Code Playgroud)

我在编写一个程序时遇到了一个非法指令错误,这是我以前从未见过的,所以我决定尝试找到一个最小的工作示例,以便我可以找出它与段错误或其他类型错误的区别。奇怪的是,程序中的微小更改似乎会使它返回段错误而不是非法指令错误。尽管如此,我还是设法将程序大幅缩减为一个较小的工作示例。话虽如此,对于一个最小的工作示例来说,该程序仍然相当大。

我的问题首先是为什么我会收到非法指令错误,其次是什么是非法指令错误。此外,如果此错误特定于我的机器,我也会感兴趣。这个程序有很多奇怪的属性。例如,似乎需要数字 -11 才能导致错误。

Ant*_*ala 5

这个

void func(int *Z){
    Z[-11] = acos(2);
}
Run Code Online (Sandbox Code Playgroud)

很可能会覆盖堆栈中的某些代码地址。很可能是退货地址。由于堆栈在 x86-64 上向下增长,并且您正在向较低地址写入内容,这意味着在保留空间放置在堆栈上的返回地址Z,所以我想这将命中来自func(). 更重要的是,您将覆盖返回地址的一半

acos(2)是一个域错误,并返回 NaN,int在我的 GCC 上转换为结果在INT_MIN那里写入...您实际上应该使用调试器并查看发生崩溃的上下文,我猜它位于包含大量fs 以十六进制表示。

当从 RIP 开始的字节未解码为有效的 x86-64 指令或其他原因时,会引发无效指令。