如果CPU嘗試執行已使用某些CPU不支持的指令編譯的二進制文件,會發生什麼情況。我特別想知道一些在舊處理器上運行的新AVX指令。執行CPU不支持的指令時會發生什麼?
我假設這可以進行測試,友好的消息理論上可以顯示給用戶。據推測,大多數低級別的圖書館都會代您進行檢查。假設你沒有做這個檢查,你會期望發生什麼?您的流程會收到什麼信號?
如果CPU嘗試執行已使用某些CPU不支持的指令編譯的二進制文件,會發生什麼情況。我特別想知道一些在舊處理器上運行的新AVX指令。執行CPU不支持的指令時會發生什麼?
我假設這可以進行測試,友好的消息理論上可以顯示給用戶。據推測,大多數低級別的圖書館都會代您進行檢查。假設你沒有做這個檢查,你會期望發生什麼?您的流程會收到什麼信號?
新指令可以設計爲「傳統兼容」或不能。
對於前者類屬於指令像tzcnt
或xacquire
有產生老年架構有效指令編碼:tzcnt
被編碼爲 rep bsf
和xacquire
只是repne
。
語義當然不同。
第二類屬於大部分新指令,AVX就是一個流行的例子。
當CPU遇到無效的或保留的編碼它生成#UD(對於未定義)異常 - 這是中斷號6.
的Linux內核entry_64.S
設置#UD的IDT條目初:
idtentry invalid_op do_invalid_op has_error_code=0
的入口點do_invalid_op
,其與宏traps.c
生成:
DO_ERROR(X86_TRAP_UD, SIGILL, "invalid opcode", invalid_op)
宏DO_ERROR
生成一個函數,該函數在同一個文件(here)中調用do_error_trap
。
do_trap
在traps.c
force_sig_info
中:
do_error_trap
使用fill_trap_info
(在同一個文件,here)創建包含Linux的信號的信息的siginfo_t
結構:
case X86_TRAP_UD:
sicode = ILL_ILLOPN;
siaddr = uprobe_get_trap_addr(regs);
break;
從那裏下面的調用發生signal.c
specific_send_sig_info
in signal.c
最終在調用違規流程的SIGILL
的信號處理程序時達到高潮。
下面的程序是一個非常簡單的例子,其產生#UD
BITS 64
GLOBAL _start
SECTION .text
_start:
ud2
我們可以使用strace
來檢查通過運行程序接收到的信號
--- SIGILL {si_signo=SIGILL, si_code=ILL_ILLOPN, si_addr=0x400080} ---
+++ killed by SIGILL +++
如預期。
作爲Cody Gray commented,圖書館通常不依靠SIGILL,相反,他們使用一個CPU dispatcher或檢查的指令的存在明確。
[信號'SIGILL'是什麼?](https://stackoverflow.com/q/7901867/608639)和朋友。據我所知,在所有Linux平臺上,包括i386,x86_64,ARM,Aarch32,Aarch64和MIPS都會引發SIGILL。 – jww
*「大概最底層的圖書館會代您檢查。」*呃,我不這麼認爲。大多數使用潛在不受支持指令的低級庫在速度上高於一切。在調用低級代碼之前,高級代碼負責驗證這些指令是否受支持。在執行它們之前,使用'CPUID'指令(在大多數編譯器中作爲內部函數公開)來驗證是否支持所需的指令集,從而避免出現無效指令異常的風險。然後顯示友好的錯誤消息。 –
停止並着火。 –