2015-06-01 1 views
3

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

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 уровней сложности стека вызовов.

+0

кажется релевантным http://stackoverflow.com/questions/5106581/how-to-get-longer-stacktrace-tombstone-from-android –

+0

Этот другой вопрос касается дампа необработанных стеков, а не обратной линии. – fadden

ответ

0

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

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

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

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

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

Аналогичный вопрос here.

Смежные вопросы