Как получить большую глубину стека вызовов в аварийных дампах на Android?

У меня есть код на C ++, который использует NDK. Когда происходит сбой в коде C ++ (на устройстве; не через эмулятор), я получаю надгробную плиту (аварийный дамп), которая содержит стек вызовов глубиной всегда 2 уровня:

I/DEBUG   ( 5089): pid: 5048, tid: 5062  >>> com.example.site <<<
I/DEBUG   ( 5089):          #00  pc 0059e08c  /data/data/com.example.site/lib/libexample.so (_ZNK10MyNamespaceAPI11MyClass12GetDataEv)
I/DEBUG   ( 5089):          #01  lr 5bc9ef2c  /data/data/com.example.site/lib/libexample.so
I/DEBUG   ( 5089):     5cc6e764  5bce3070  /data/data/com.example.site/lib/libexample.so
I/DEBUG   ( 5089):     5cc6e774  5bce309c  /data/data/com.example.site/lib/libexample.so
I/DEBUG   ( 5089):     5cc6e784  5bce2af4  /data/data/com.example.site/lib/libexample.so
I/DEBUG   ( 5089):     5cc6e788  5c27ea9c  /data/data/com.example.site/lib/libexample.so

Есть ли способ настроить мое приложение или Android, чтобы обеспечить более подробную информацию и глубину в стеке вызовов, распечатанном в аварийный дамп? Что на самом деле определяет это? Я видел несколько примеров, когда люди получают до 15 уровней глубины стека вызовов.

3

Решение

Механизм обратной трассировки, который развился за последние несколько лет, показывает столько кадров, сколько он может найти (до фиксированного предела 32, IIRC). Он остановится рано, если что-то помешает ему пройти дальше по стеку.

Механизм вызова в ARM помещает адрес возврата в регистр связи (LR), но компилятору разрешено передавать его в стек. Для функций «noreturn» его технически не нужно устанавливать вообще. Существуют псевдооперации на ассемблере, которые добавляют метаданные, которые помогают разобраться, где можно найти адрес возврата, и в более поздних версиях Android, которые должны все работать.

Когда вы получаете трассировку стека с двумя глубинами, это означает, что размотка не удалась в текущем методе, и она может показать вам только значение программного счетчика (ПК) и значение, которое оказывается в LR.

Убедитесь, что вы компилируете с -g включить отладку.

Вызывающая функция вызывается напрямую из JNI? В некоторых старых версиях Android трассировка останавливается на мосту вызовов JNI из-за структуры кода, хотя это было исправлено в Dalvik назад в 2011. Последние устройства используют Art, хотя, как я ожидаю, по-другому.

Подобный вопрос Вот.

0

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector