C非法指令
C illegal instruction
下面是我编写的 c 程序的打印输出,我的演示 运行,最后是关于我的编译器的一些信息。
➜ 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
我在编写程序时遇到了非法指令错误,这是我以前从未见过的错误,所以我决定尝试找到一个最小的工作示例,以便找出它与段错误或其他错误的区别其他类型的错误。奇怪的是,程序中的微小改动似乎会 return 给出段错误而不是非法指令错误。尽管如此,我还是设法将程序大幅缩减为一个更小的工作示例。话虽如此,对于最小的工作示例来说,该程序仍然相当大。
我的问题首先是为什么会出现非法指令错误,其次是什么是非法指令错误。此外,如果此错误特定于我的机器,我也会感兴趣。这个程序有很多奇怪的属性。例如,似乎需要数字 -11 才能导致错误。
这个
void func(int *Z){
Z[-11] = acos(2);
}
很可能碰巧覆盖了堆栈中的某些 code 地址。很可能是 return 地址。由于堆栈在 x86-64 上向下增长,并且您正在将内容写入较低地址,这意味着 return 地址被放置在堆栈 after space for Z
是保留的,所以我想这会从 func()
命中 return 地址。更重要的是,您将覆盖 return 地址的 一半 。
acos(2)
是域错误,returns NaN 在我的 GCC 上转换为 int
导致 INT_MIN
被写在那里......你应该实际上使用调试器并查看发生崩溃的上下文,我猜它是在一个地址中,该地址在其十六进制表示中包含很多 f
s。
当从 RIP 开始的字节未解码为有效的 x86-64 指令或 for other reasons.
时,将引发无效指令
下面是我编写的 c 程序的打印输出,我的演示 运行,最后是关于我的编译器的一些信息。
➜ 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
我在编写程序时遇到了非法指令错误,这是我以前从未见过的错误,所以我决定尝试找到一个最小的工作示例,以便找出它与段错误或其他错误的区别其他类型的错误。奇怪的是,程序中的微小改动似乎会 return 给出段错误而不是非法指令错误。尽管如此,我还是设法将程序大幅缩减为一个更小的工作示例。话虽如此,对于最小的工作示例来说,该程序仍然相当大。
我的问题首先是为什么会出现非法指令错误,其次是什么是非法指令错误。此外,如果此错误特定于我的机器,我也会感兴趣。这个程序有很多奇怪的属性。例如,似乎需要数字 -11 才能导致错误。
这个
void func(int *Z){
Z[-11] = acos(2);
}
很可能碰巧覆盖了堆栈中的某些 code 地址。很可能是 return 地址。由于堆栈在 x86-64 上向下增长,并且您正在将内容写入较低地址,这意味着 return 地址被放置在堆栈 after space for Z
是保留的,所以我想这会从 func()
命中 return 地址。更重要的是,您将覆盖 return 地址的 一半 。
acos(2)
是域错误,returns NaN 在我的 GCC 上转换为 int
导致 INT_MIN
被写在那里......你应该实际上使用调试器并查看发生崩溃的上下文,我猜它是在一个地址中,该地址在其十六进制表示中包含很多 f
s。
当从 RIP 开始的字节未解码为有效的 x86-64 指令或 for other reasons.
时,将引发无效指令