开发者

SIGILL in Android NDK code

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 was SIGILL, 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜