I have an NDK app out on market and got a native crash report about a SIGILL
signal. (I use google breakpad to generate native crash reports.) Here are the details:
- My app is compiled for
armea开发者_运维百科bi-v7a
, with NEON support. - It crashed on a NVIDIA Tegra 2 Processor, which is ARM-7 (Cortex-A9).
- It happens every time. (contacted the user)
- The crash address was at
0x399cc
, the signal wasSIGILL
, and it's in my code.
Registers and disassembly:
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>
Full source and assembler available here (it's short, basically 2 lines of C++.)
You can see that 0x399cc
is in the middle of the fconstd
instruction. According to arm.com this instruction was added in VFP-v3
, which should (I think) be available in any modern processor.
What could be going on? Does the fact that the address is in the middle of an instruction point to a corrupt pointer somewhere? (Note that the backtrace makes perfect sense, so it's not like this function was somehow called on accident.) Or is it something else?
Ok, I got it: the NVIDIA Tegra 2 only has 16 64-bit GPU registers, and therefore to target it you must compile using -mfpu=vfpv3-d16
. The instruction in question uses register d16
, which is "just too many". :(
Here is a reference to an NVIDIA forum where an employee mentions this limitation: http://developer.nvidia.com/tegra/forum/optimal-performance-guidelines
Try to put *.so in a folder called 'externallibs' and use it to build by ndk-build, after copy and paste *.so in armeabi-v7a folder. It helps me. An other solutions is to remove the Neon Support if it is possible
(I know it's answered but this is the first result i get when searching for NDK SIGILL ARM.)
At least on ARM 32 bits devices (i think it's an architecture thing and not dependent on clang flags or the NDK but i'll gladly be corrected), if you have a function that returns something, like a int getSomeThing();
and you don't have a return
statement you risk a misterious SIGILL at the end of said function.
So this:
int returnSomething() {
// do stuff
if(whatever) {
// more code
} // SIGILL at the end of the last block or instruction
// no return 0; here
}
will trigger it.
精彩评论