2011-08-18 19 views
8

Tengo una aplicación NDK en el mercado y obtuve un informe de fallos nativo sobre una señal SIGILL. (Yo uso Google Breakpad para generar informes de fallos nativos.) Aquí están los detalles:SIGILL en Android Código NDK

  • Mi aplicación está compilado para armeabi-v7a, de apoyo NEON con.
  • Se estrelló en un procesador NVIDIA Tegra 2, que es ARM-7 (Cortex-A9).
  • Ocurre todo el tiempo. (contactó con el usuario)
  • La dirección del bloqueo estaba en 0x399cc, la señal era SIGILL, y está en mi código.

Registros y desmontaje:

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> 

fuente completo y el ensamblador disponibles here (es corto, básicamente 2 líneas de C++.)

Se puede ver que 0x399cc está en el medio de la fconstd instrucción. De acuerdo con arm.com esta instrucción se agregó en VFP-v3, que debería (creo) estar disponible en cualquier procesador moderno.

¿Qué podría estar pasando? ¿El hecho de que la dirección se encuentre en el middle de una instrucción apunta a un puntero corrupto en alguna parte? (Tenga en cuenta que la traza inversa tiene mucho sentido, por lo que no es como si esta función fuera llamada de alguna manera por accidente.) ¿O es algo más?

+0

FWIW, una respuesta aparentemente oficial de NVIDIA con respecto al soporte de VFPv3 en el Tegra 2 se puede encontrar aquí. (Spoiler: lo hace, por lo que las personas que lo consideren como el problema, ya que VFPv3 está marcado como "opcional" en la serie Cortex-A9, debe buscar más). http://developer.nvidia.com/tegra/foro/hacer es-tegra-2-support-vfpv3 –

+0

En cuanto al Google Breakpad en Android, hay una pregunta abierta sobre esto si quieres algunos puntos fáciles :) http://stackoverflow.com/questions/9752759/using-google-breakpad -for-android-ndk – olafure

Respuesta

15

Ok, lo tengo: el NVIDIA Tegra 2 solo tiene 16 registros de GPU de 64 bits, y por lo tanto para apuntarlos debe compilar usando -mfpu=vfpv3-d16. La instrucción en cuestión utiliza el registro d16, que es "demasiados". :(

Aquí es una referencia a un foro de NVIDIA, donde un empleado menciona esta limitación: http://developer.nvidia.com/tegra/forum/optimal-performance-guidelines

+0

Eso es todo. Tampoco es compatible con las instrucciones NEON. Ahora la pregunta es ... ¿es seguro asumir que todos los procesadores 'armeabi-v7a' tienen soporte' vfpv3-d16'? ¿Y es posible aprovechar la FPU mientras todavía se especifica '-mfloat-abi = softfp' (requerido para Android?) – tmandry

+5

En realidad, casi había incluido una referencia al sitio del proyecto Debian ARMEL para esto, pero afirmaron que" vfpv3-d16 "era un buen" denominador común ". También (misma referencia), softfp permite al compilador "tomar decisiones inteligentes sobre cuándo y si genera instrucciones de FPU emuladas o reales dependiendo del tipo de FPU elegido", por lo que parece que sí: podrá aprovechar la FPU con esa bandera. http://wiki.debian.org/ArmHardFloatPort/VfpComparison –

+0

¡Excelente información! Muchas gracias. – tmandry

0

Trate de poner * .so en una carpeta llamada '' externallibs y utilizarlo para construir por NDK-construcción, después de copiar y pegar * .so en la carpeta armeabi-v7a. Me ayuda Otra solución es eliminar el soporte de neón si es posible