0

下面是我编写的 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

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

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

4

1 回答 1

5

这个

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

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

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

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

于 2020-09-01T05:16:29.887 回答