非法指令(Illegal Instruction)问题定位

本文探讨了非法指令(SIGILL)问题的原因,包括错误修改代码段、指令集演进、工具链Bug和内存访问问题。提供了错误排查指南,强调了非法指令处理、内核及用户空间的问题分析和定位方法,例如通过hexdump对比进程内存和代码段。
摘要由CSDN通过智能技术生成

 关键词:Illegal Instruction、SIGILL等。

 

进程在运行过程中会收到SIGILL信号,此类错误是由操作系统发送给进程的。

SIGILL是某个进程中的某一句不能被CPU识别指令,这些指令可能是一些形式错误、未知或者特权指令。

1. SIGILL原因

1.1 错误修改代码段

进程代码段中数据是作为指令运行的,如果不小心代码段被错误覆盖,那么CPU可能无法识别对应的代码,进而造成Illegal Instruction。

同样,如果栈被不小心覆盖了,造成返回地址错误、CPU跳转到错误地址,执行没有意义的内存数据,进而造成Illegal Instruction。

进一步可以认为,任何导致代码段错误的问题都可能带来Illegal Instruction。

1.2 指令集演进

CPU的指令集在不停演进,如果将较新指令集版本的程序在老版本CPU上运行,则老版本CPU运行时会有Illegal Instruction问题。

1.3 工具链Bug

编译器(汇编器或者连接器)自身的bug,有可能生成CPU无法识别的指令。

1.4 内存访问对齐或浮点格式问题

出现错误的指令可能和访存地址指令有关。 另外,浮点数的格式是否符合IEEE的标准也可能会有影响。

2. 错误排查指南

  • 程序中有没有特权指令、或者访问特权寄存器

  • 有没有将在较新CPU上编译得到的可执行文件拿到老CPU上运行------------这种问题是100%复现,只需要查看对应汇编程序即可知道大概。

  • 程序中有没有嵌入式汇编,先检查。-------------------------------------------------编译器bug。

    • 一般编译器很少会生成有这种问题的代码

    • X86平台上要尤其注意64位汇编指令和32位汇编指令的混用问题

  • 程序有在进程代码段空间写数据的机会吗?----------------------------------------下面的分析就是代码段被非法修改。还可能是意见存在问题,DDR中数据正确,从DDR读取的数据经过总线产生数据突变异常。

  • 栈操作够安全吗?--------------------------------------------------------------------------如果异常PC指向栈,那么即是栈被非法修改。

  • 注意程序的ABI是否正确------------------------------------------------------------------100%复现问题,只需要检查ABI说明书即可。

    • 尤其是动态链和静态链是否处理的正确,尽量避免动态链的可执行文件调用错误库的问题(ARM的EABI,MIPS的N32/O32/N64都很可能出这种问题)

  • 用的工具链靠谱吗? 

3. Illegal Instruction处理

CK异常向量VEC_ILLEGAL对应非法指令错误,出现问题的时候内核输出“Illegal instruction Error”,然后输出寄存去、相关代码段、栈等信息;最后发送SIGILL信号给进程。

asmlinkage void trap_c(struct pt_regs *regs)
{
    int sig;
    unsigned long vector;
    siginfo_t info;

    vector = (mfcr("psr") >> 16) & 0xff;

    switch (vector) {
...
        case VEC_ILLEGAL:
#ifndef CONFIG_CPU_NO_USER_BKPT
        if (*(uint16_t *)instruction_pointer(regs) != 0x1464)
#endif
        {
            sig = SIGILL;
            pr_err("Illegal instruction Error\n");
            show_regs(regs);
            break;
        }
...
    }
    send_sig(sig, current, 0);---------------------------------------------发送SIGILL给当前进程。
}

void show_regs(struct pt_regs *fp)
{
    unsigned long   *sp;
    unsigned char   *tp;
    int    i;

    pr_info("\nCURRENT PROCESS:\n\n");
    pr_info("COMM=%s PID=%d\n", current->comm, current->pid);

    if (current->mm) {
        pr_info("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
               (int) current->mm->start_code,
               (int) current->mm->end_code,
               (int) current->mm->start_data,
               (int) current->mm->end_data,
               (int) current->mm->end_data,
               (int) current->mm->brk);
        pr_info("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
               (int) current->mm->start_stack,
               (int) (((unsigned long) current) + 2 * PAGE_SIZE));
    }

    pr_info("PC: 0x%08lx (%pS)\n", (long)fp->pc, (void *)fp->pc);
    pr_info("LR: 0x%08lx (%pS)\n", (
### 回答1: "illegal instruction (core dump)" 意思是程序在运行时遇到了非法指令,导致程序崩溃,并生成了一个 "core dump" 文件。这通常是由于程序代码中存在错误或者程序使用了不兼容的硬件或操作系统功能导致的。 ### 回答2: illegal instruction (core dump)是指某个程序在执行时出现了非法指令,并因此导致崩溃,并生成核心转储文件(core dump)。这个错误需要通过分析崩溃现象来确定原因。 首先,我们需要查阅相关的错误日志,以及检查程序运行的相关环境,包括操作系统版本、CPU架构、程序编译器版本等。这有助于我们快速锁定原因。 一般情况下,illegal instruction (core dump)是由于程序在执行时执行了不支持的指令,或是执行了内存损坏的代码造成的。这些情况通常是由程序员在编写代码时没有考虑到特定环境下的限制,或是代码中出现了缺陷导致的。 针对这个错误,我们可以通过以下几个方式进行修复: 1.升级程序编译器或运行环境,并重新编译程序。这能够保证在新的环境下程序能够正确执行。 2.检查代码,确认代码中没有出现不支持的指令或内存损坏等问题。 3.通过使用调试工具,如GDB等,来跟踪程序的执行过程,定位到具体的错误代码,并修改代码以避免出现这些问题。 总之,illegal instruction (core dump)是一个常见的程序错误,需要通过仔细的分析和调试才能够解决。在编写程序时,我们需要考虑到不同运行环境的限制,并尽可能避免出现缺陷,以提高程序的稳定性和可靠性。 ### 回答3: Illegal instruction (core dump)是一种计算机错误。简而言之,计算机执行了无法理解的指令,并且因为这个错误导致程序的终止。这种错误通常会生成一个core dump文件,这个文件包含了程序崩溃时的内存状态,可以用于调试程序。 Illegal instruction错误通常是由于以下几种原因引起的: 1.硬件损坏:如果CPU或者内存损坏或者出现故障,计算机就可能执行不正常的指令,导致Illegal instruction错误。 2.软件更新:如果操作系统或者应用程序发生更新,但是旧程序与新程序不兼容,就可能导致Illegal instruction错误。 计算机会尝试执行无法识别或无法理解的操作码。 3.编译错误:编译器将代码转换成机器指令,如果编译器生成了错误的指令,就可能导致Illegal instruction错误。 如何解决Illegal instruction错误?这需要根据具体情况来定。可能需要检查计算机硬件是否正常,重新安装相关软件,或者对程序进行调试。确保代码正确,任何未定义的行为都被考虑到。 同时保持软件和硬件更新到最新版本可以预防这种错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值