我有一个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++。)
你可以看到0x399cc
在fconstd
指令的中间。根据arm.com,这个指令是在VFP-v3
中添加的,(我认为)它应该在任何现代处理器中可用。
这是怎么回事?地址在指令的 * 中间 * 这一事实是否指向了某个损坏的指针?(注意,回溯是完全有意义的,所以这个函数不是偶然被调用的。)或者是其他原因?
3条答案
按热度按时间0s0u357o1#
好的,我知道了:NVIDIA Tegra 2只有16个64位GPU寄存器,因此要将其作为目标,您必须使用
-mfpu=vfpv3-d16
进行编译。有问题的指令使用了寄存器d16
,这“太多了”。:(以下是一个NVIDIA论坛的参考资料,其中一名员工提到了这一限制:http://developer.nvidia.com/tegra/forum/optimal-performance-guidelines
sqougxex2#
试着把 *.so放在一个叫做“externallibs”的文件夹中,然后用它来构建ndk-build,在复制并粘贴 *.so到armeabi-v7 a文件夹中之后。这对我很有帮助。另一个解决方案是如果可能的话删除氖支持
uqjltbpv3#
(我知道它的答案,但这是我得到的第一个结果时,搜索NDK SIGILL ARM.)
至少在ARM 32位设备上(我认为这是一个架构问题,不依赖于clang标志或NDK,但我很高兴被纠正),如果你有一个返回一些东西的函数,比如
int getSomeThing();
,而你没有return
语句,你就有可能在所说的函数的结尾出现一个神秘的SIGILL。所以这个:
会触发它。