【问题标题】:What causes signal 'SIGILL'?是什么导致信号“SIGILL”?
【发布时间】:2011-12-15 15:45:30
【问题描述】:

我正在使用 NDK 和 GCC 将一些 C++ 代码移植到 Android。代码基本上运行。有一次,在 Eclipse 中调试时,调用

Dabbler::Android::Factory* pFactory = new Dabbler::Android::Factory;

导致此错误:

Thread [1] (Suspended: Signal 'SIGILL' received. Description: Illegal instruction.) 
    1 <symbol is not available> 0x812feb44

这是什么意思?编译器是否出于某种原因生成了非法代码?我在构造函数中有一个断点(它什么都不做),它没有被命中。我已经完成了完整的重建。

我做错了什么会导致这个问题?

【问题讨论】:

    标签: android c++ android-ndk porting


    【解决方案1】:

    LeetCode 的在线编译器和开发环境会针对在我的桌面 IDE 中不会产生相同错误的错误生成 SIGILL 错误。

    例如,具有越界索引的数组访问:

    ["foo", "bar"][2]
    

    LeetCode 的编译器只显示错误:

    运行时错误 进程退出,信号SIGILL

    在本地 Xcode 游乐场中,同样的代码会导致 the error

    错误:执行被中断,原因:EXC_BREAKPOINT (code=1, subcode=0x18f2ea5d8)。
    进程一直停留在中断点,使用“thread return -x”返回表达式求值前的状态。

    只有在完整的 Xcode 项目编译并运行时才会报告实际错误:

    线程 1:致命错误:索引超出范围

    【讨论】:

      【解决方案2】:

      确保所有具有非 void 返回类型的函数都有 return 语句。

      虽然一些编译器会自动提供默认返回值,但其他编译器会在运行时发送一个 SIGILL 或 SIGTRAP,以便在没有返回值的情况下离开函数。

      【讨论】:

      • 您不知道我花了多长时间寻找 SIGILL (QT + Android) 背后的原因,只是为了在函数中找到一个缺少的 return 语句(受您的回复启发)。谢谢。
      • @Vega4 你用的是什么编译器?谢谢!
      【解决方案3】:

      它可能是一些未初始化的函数指针,特别是如果您的内存已损坏(那么指向无效对象的 C++ 错误指针的虚假 vtable 可能会给出这种情况)。

      顺便说一句,gdb 观察点和跟踪点以及valgrind 可能对调试此类问题有用(如果可用)。或者一些address sanitizer

      【讨论】:

      • 对我来说,我没有从应该返回 int 的函数中返回任何值。所以有点与这个答案有关。不知道它是如何编译的。
      【解决方案4】:

      这意味着 CPU 试图执行它不理解的指令。我猜这可能是由损坏引起的,或者可能是针对错误的架构编译的(在这种情况下,我会认为 O/S 会拒绝运行可执行文件)。不完全确定根本问题是什么。

      【讨论】:

      • 执行无效指令的另一个原因是跳转到不在程序区域中的地址。
      • 奇怪,当我用 clang 编译时,我得到了这个,但它在 gcc 上工作得很好
      猜你喜欢
      • 2013-07-04
      • 2021-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多