c - 在不调试的情况下查找导致 Illegal Instruction 错误的汇编指令

标签 c linux assembly x86-64 yasm

在运行我用汇编编写的程序时,出现Illegal instruction 错误。有没有办法知道是哪条指令导致了错误,而无需调试,因为我运行的机器没有调试器或任何开发系统。换句话说,我在一台机器上编译并在另一台机器上运行。我无法在正在编译的机器上测试我的程序,因为它们不支持 SSE4.2。尽管如此,我运行该程序的机器确实支持 SSE4.2 指令。

我想这可能是因为我需要告诉汇编程序 (YASM) 识别 SSE4.2 指令,就像我们通过向它传递 -msse4.2 标志来处理 gcc 一样。或者你认为这不是原因?知道如何告诉 YASM 识别 SSE4.2 指令吗?

也许我应该捕获 SIGILL发出信号,然后对 SA_SIGINFO 进行解码,以查看程序进行了何种非法操作。

最佳答案

最近遇到132退出状态码(128+4:程序被信号中断+非法指令信号)导致崩溃。以下是我找出导致崩溃的指令的方法。

首先,我启用了核心转储:

$ ulimit -c unlimited

有趣的是,我运行二进制文件的文件夹包含一个名为 core 的文件夹。我不得不告诉 Linux 将 PID 添加到核心转储中:

$ sudo sysctl -w kernel.core_uses_pid=1

然后我运行我的程序并得到一个名为 core.23650 的核心。我用 gdb 加载了二进制文件和核心。

$ gdb program core.23650

进入 gdb 后,它显示了以下信息:

Program terminated with signal SIGILL, Illegal instruction.
#0  0x00007f58e9efd019 in ?? ()

这意味着我的程序因 0x00007f58e9efd019 地址内存中的非法指令而崩溃。然后我切换到 asm layout 来检查最后执行的指令:

(gdb) layout asm
>|0x7f58e9efd019  vpmaskmovd (%r8),%ymm15,%ymm0
 |0x7f58e9efd01e  vpmaskmovd %ymm0,%ymm15,(%rdi)
 |0x7f58e9efd023  add    $0x4,%rdi
 |0x7f58e9efd027  add    $0x0,%rdi

导致错误的是指令vpmaskmovd。显然,我试图在不支持 AVX2 指令集的系统上运行针对 AVX2 架构的程序。

$ cat /proc/cpuinfo | grep avx2

最后,我确认了vpmaskmovd is an AVX2 only instruction .

关于c - 在不调试的情况下查找导致 Illegal Instruction 错误的汇编指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10354147/

相关文章:

linux - 使用vmware_vm_shell模块使用ansible配置Linux VM时变成su?

c - 如果传递了冲突的编译器标志,GCC 会如何表现?

c - C中的多态数据结构

android - 使用 ndk-gdb 调试时调用参数丢失。堆栈跟踪有效

node.js - 在 Ubuntu 18.04 上安装 ReactJS——npm 权限被拒绝

regex - 重复正则表达式替换为 SED

gcc - 为什么我们不能直接从堆栈帧移1个字节到寄存器?

c++ - 如何向 MIPS 中的函数添加 4 个以上的参数?

c - 尝试交换节点数据

c - 如何修改文件 'jonesforth.S' 以便它可以返回到 C 调用函数而不导致段错误?