Android NDK代码中的SIGILL

SIGILL in Android NDK code

本文关键字:SIGILL 代码 NDK Android      更新时间:2023-10-16

我在市场上有一个NDK应用程序,得到了一个关于SIGILL信号的本机崩溃报告。(我使用google breakpad生成原生崩溃报告。)以下是详细信息:

  • 我的应用程序编译为armeabi-v7a NEON支持
  • 它在NVIDIA Tegra 2处理器上崩溃了,这是ARM-7 (Cortex-A9)。
  • 这种事每次都会发生。(已联系用户)
  • 崩溃地址是0x399cc,信号是SIGILL,它在我的代码中。

寄存器和反汇编:

 r4 = 0x001d50f0    r5 = 0x001d50f0    r6 = 0x598e2a3c    r7 = 0x00000000
 r8 = 0x00000001    r9 = 0x001c22b0   r10 = 0x00000000    fp = 0x81216264
 sp = 0x598e2a18    lr = 0x816399cb    pc = 0x816399cc
0x000399c6 <_ZN8Analyzer15setExpAvgFactorEi+22>:    blx 0x30508
0x000399ca <_ZN8Analyzer15setExpAvgFactorEi+26>:    fconstd d16, #7
0x000399ce <_ZN8Analyzer15setExpAvgFactorEi+30>:    vldr    d17, [pc, #32]  ; 0x399f2 <_ZN8Analyzer15setExpAvgFactorEi+66>

完整的源代码和汇编程序在这里(它很短,基本上是2行c++)

可以看到0x399ccfconstd指令的中间。根据arm.com的说法,这条指令是在VFP-v3中添加的,应该(我认为)在任何现代处理器中都可以使用。

发生了什么事?地址在指令的中间指向某个地方的损坏指针的事实吗?(注意,反向跟踪是完全有意义的,所以它不像这个函数是意外调用的。)还是其他原因?

好的,我明白了:NVIDIA Tegra 2只有16位GPU寄存器,因此要针对它必须使用-mfpu=vfpv3-d16进行编译。有问题的指令使用寄存器d16,这是"太多了"。(

这里是一个NVIDIA论坛的参考资料,其中一个员工提到了这个限制:http://developer.nvidia.com/tegra/forum/optimal-performance-guidelines

尝试输入*。所以在一个名为"externallibs"的文件夹中,使用它通过ndk-build来构建,之后复制粘贴*。在armeabi-v7a文件夹中。这对我有帮助。另一个解决方案是删除霓虹支持,如果可能的话

(我知道它回答了,但这是我在搜索NDK SIGILL ARM时得到的第一个结果。)

至少在ARM 32位设备上(我认为这是一个架构的事情,不依赖于clang标志或NDK,但我很乐意纠正),如果你有一个函数返回一些东西,比如int getSomeThing();,而你return语句,你冒着在该函数末尾出现神秘SIGILL的风险。

:

int returnSomething() {
  // do stuff
  if(whatever) {
    // more code
  } // SIGILL at the end of the last block or instruction
  // no return 0; here
}