usos usadas seguridad rombo procell piratas pilas nfpa hoja duracell caracteristicas bateria alcalinas c++ arm android-ndk

c++ - usadas - pilas procell



los rastros de pila se detienen en el registro de hoja(lr) (2)

¿Tienes toda la información de depuración ( -g3 ) -g3 ?

A Gcc le gusta usar el lr como un registro normal. Recuerde que una función que no es una hoja se parece a

push {lr} ; .. setup args here etc. bl foo ; call a function foo ; .. work with function results pop {pc}

Una vez que empujó lr a la pila, el compilador puede usarlo casi libremente; lr se sobrescribirá solo mediante llamadas a funciones. Por lo tanto, es bastante probable que exista algún valor intermedio en lr .

Esto debe indicarse en la información de depuración que genera el compilador, para que el depurador sepa que tiene que mirar el valor de la pila en lugar de lr .

A menudo veo rastros de pila de ARM (léase: rastros de pila de NDK de Android) que terminan con un puntero lr , así:

#00 pc 001c6c20 /data/data/com.audia.dev.qt/lib/libQtGui.so #01 lr 80a356cc /data/data/com.audia.dev.rta/lib/librta.so

Sé que lr significa link register en ARM y otras arquitecturas, y que es una manera rápida de almacenar una dirección de retorno, pero no entiendo por qué siempre parece almacenar una dirección inútil. En este ejemplo, 80a356cc no se puede asignar a ningún código que use addr2line o gdb .

¿Hay alguna forma de obtener más información? ¿Por qué debe el rastreo detenerse en la dirección de lr todos modos?


Tropezó con la respuesta finalmente. Solo tenía que ser más observador. Mire el siguiente rastro de la pila corta y la información que viene después:

#00 pc 000099d6 /system/lib/libandroid.so #01 lr 80b6c17c /data/data/com.audia.dev.rta/lib/librta.so code around pc: a9d899b4 bf00bd0e 2102b507 aa016d43 28004798 a9d899c4 9801bfa8 bf00bd0e 460eb573 93004615 a9d899d4 6d842105 462b4632 200047a0 bf00bd7c a9d899e4 b100b510 f7fe3808 2800edf4 f04fbf14 a9d899f4 200030ff bf00bd10 b097b5f0 4614af01 code around lr: 80b6c15c e51b3078 e5933038 e5932024 e51b302c 80b6c16c e1a00002 e3a01000 e3a02000 ebfeee5c 80b6c17c e1a03000 e50b303c e51b303c e1a03fa3 80b6c18c e6ef3073 e3530000 0a000005 e59f34fc 80b6c19c e08f3003 e1a00003 e51b103c ebfeebe6

Ahora la dirección lr sigue siendo una dirección 80xxxxxx que no nos es útil.

La dirección que imprime desde la pc es 000099d6 , pero mira la siguiente sección, el code around pc . La primera columna es una lista de direcciones (se puede ver por el hecho de que se incrementa en 16 cada vez). Ninguna de esas direcciones se parece a la dirección de la pc , a menos que corte los primeros 16 bits. Entonces notará que a9d899d4 debe corresponder a 000099d4 , y el código donde el programa se detuvo está a dos bytes de eso.

El rastreo de la pila de Android parece haber "cortado" los primeros 2 bytes de la dirección de la pc para mí, pero por alguna razón no lo hace para las direcciones en el registro de la hoja. Lo que nos lleva a la solución:

En resumen, pude cortar los primeros 16 bits de la dirección 80b6c17c para convertirlo en 0000c17c , y hasta ahora eso me ha dado una dirección de código válida cada vez que puedo buscar con gdb o addr2line . ( Editar: he encontrado que en realidad son los primeros 12 bits o los primeros 3 dígitos hexadecimales. Puedes decidirlo por ti mismo mirando la salida de seguimiento de pila como describí anteriormente). Puedo confirmar que es la dirección de código correcta como bien. ¡Esto definitivamente ha hecho que la depuración sea mucho más fácil!