簡體   English   中英

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

我在編寫一個程序時遇到了非法指令錯誤,這是我以前從未見過的,所以我決定嘗試找到一個最小的工作示例,以便弄清楚是什么將它與段錯誤或其他類型的錯誤區分開來。 奇怪的是,程序中的微小改動似乎會返回到段錯誤而不是非法指令錯誤。 N.netheless,我已經設法將程序大幅縮減為一個更小的工作示例。 話雖如此,對於最小的工作示例來說,該程序仍然相當大。

我的問題首先是為什么我會收到非法指令錯誤,其次是什么是非法指令錯誤。 此外,如果此錯誤特定於我的機器,我也會感興趣。 這個程序有很多奇怪的屬性。 例如,似乎需要數字 -11 才能導致錯誤。

這個

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

很可能碰巧覆蓋了堆棧中的某些代碼地址。 很可能是回郵地址。 由於堆棧在 x86-64 上向下增長,並且您正在將內容寫入較低地址,這意味着在為Z保留空間后將返回地址放在堆棧上,所以我想這會命中func()的返回地址func() 更重要的是,您將覆蓋一半的返回地址。

acos(2)是一個域錯誤,並返回 NaN,它在我的 GCC 上轉換為int導致INT_MIN被寫入那里......你應該實際使用調試器並查看崩潰發生的上下文,我猜它是在在其十六進制表示中包含大量f的地址。

當從 RIP 開始的字節未解碼為有效的 x86-64 指令或出於其他原因時,將引發無效指令。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM