Android NDK代码中的SIGILL
SIGILL in Android NDK code
我在市场上有一个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++)
可以看到0x399cc
在fconstd
指令的中间。根据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
}
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 孤立代码块在结构中引发异常
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 此代码是否违反一个定义规则
- 为什么我的代码在输出中增加了93天
- 我的简单if-else语句是如何无法访问的代码
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 为什么在这个代码结束循环中没有得到结束
- 为什么这个C++代码会让 SIGILL ideone.com
- Android NDK代码中的SIGILL