assembly Android NDK代码中的SIGILL

3wabscal  于 2022-11-13  发布在  Android
关注(0)|答案(3)|浏览(148)

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

  • 我的应用程序是针对armeabi-v7a编译的,支持氖。
  • 它在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>

完整的源代码和汇编程序可用here(它很短,基本上是2行C++。)
你可以看到0x399ccfconstd指令的中间。根据arm.com,这个指令是在VFP-v3中添加的,(我认为)它应该在任何现代处理器中可用。
这是怎么回事?地址在指令的 * 中间 * 这一事实是否指向了某个损坏的指针?(注意,回溯是完全有意义的,所以这个函数不是偶然被调用的。)或者是其他原因?

0s0u357o

0s0u357o1#

好的,我知道了:NVIDIA Tegra 2只有16个64位GPU寄存器,因此要将其作为目标,您必须使用-mfpu=vfpv3-d16进行编译。有问题的指令使用了寄存器d16,这“太多了”。:(
以下是一个NVIDIA论坛的参考资料,其中一名员工提到了这一限制:http://developer.nvidia.com/tegra/forum/optimal-performance-guidelines

sqougxex

sqougxex2#

试着把 *.so放在一个叫做“externallibs”的文件夹中,然后用它来构建ndk-build,在复制并粘贴 *.so到armeabi-v7 a文件夹中之后。这对我很有帮助。另一个解决方案是如果可能的话删除氖支持

uqjltbpv

uqjltbpv3#

(我知道它的答案,但这是我得到的第一个结果时,搜索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
}

会触发它。

相关问题