трассировки стека останавливаются перед получением моего кода (на Android с использованием NDK) - PullRequest
11 голосов
/ 15 июня 2011

Я разрабатываю на Android 2.3.x, используя NDK r5b. Иногда мой код падает, и я хотел бы знать, где. Я уже знаю, как получить соответствующую строку в моем приложении, когда у меня есть указатель (то есть из трассировки стека Android)

Однако, часто я вижу бесполезные трассировки стека, как это (полная трассировка стека):

     #00  pc 0006561a  /system/lib/egl/libGLESv2_adreno200.so
     #01  pc 0006b900  /system/lib/egl/libGLESv2_adreno200.so
     #02  pc 0005aac8  /system/lib/egl/libGLESv2_adreno200.so
     #03  pc 0001687a  /system/lib/egl/libGLESv1_CM_adreno200.so
     #04  pc 000096ce  /system/lib/egl/libGLESv1_CM_adreno200.so

или это:

(gdb) bt
#0  0xafd0c51c in epoll_wait () from /Volumes/SecureCode/webos/rta/android/obj/local/armeabi/libc.so
#1  0xa81216a6 in ?? ()

, которые вообще не упоминают мой код.

Есть ли какой-нибудь способ получить лучшие трассировки стека, чем этот? Почему некоторые библиотечные функции «непрозрачны» в том, что они не позволяют обратному следу «видеть сквозь» вызывающую функцию, вызывая остановку в трассировке стека?

Насколько я могу судить, единственный способ отладить подобную проблему - это использовать ведение журнала в каждой точке программы и / или проходить через каждую строку с помощью gdb.

Имеются ли ПЗУ с отладочными версиями этих библиотек Android вместо исполняемых, и это поможет? (Я использую один телефон исключительно для разработки, поэтому меня не интересует сохранение полной функциональности.) ( На самом деле , я заметил, что путь к libc.so в приведенном выше gdb трассировка стека находится в каталоге моего приложения. Могу ли я просто упаковать его с другим (отладка) libc.so, и это поможет?)

Последнее, что может помочь: в приведенной выше трассировке стека от logcat (первая) моя библиотека упоминается в дампе необработанного стека:

stack:
  ...
  ...
  4471cb88  00000028  
  4471cb8c  afd4649c  
  4471cb90  80b4eb71  /data/data/com.audia.dev.rta/lib/librta.so
  4471cb94  00299180  
  ...
  ...

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

Ответы [ 5 ]

6 голосов
/ 27 июня 2011

Есть ли какой-нибудь способ получить лучшие трассировки стека, чем этот?

Насколько я знаю, вы должны создавать и писать образ Android самостоятельно.Он позволяет вам иметь все полные символы Android (исполняемые файлы и общие библиотеки), кроме проприетарных общих библиотек.

Также предусмотрено использование символов с использованием gdb.

$ adb shell setprop debug.db.uid 32767
$ adb forward tcp:5039 tcp:5039

/*
 program terminated and debuggerd caught exception like the following.
 Use the PID number for gdbclient 3rd parameter.
 I/DEBUG   ( 2154): ******************************************************** 
 I/DEBUG   ( 2154): * Process 2508 has been suspended while crashing.  To
 I/DEBUG   ( 2154): * attach gdbserver for a gdb connection on port 5039:
 I/DEBUG   ( 2154): *
 I/DEBUG   ( 2154): *     adb shell gdbserver :5039 --attach 2508 &
 I/DEBUG   ( 2154): *
 I/DEBUG   ( 2154): * Press HOME key to let the process continue crashing.
 I/DEBUG   ( 2154): ********************************************************)
*/

$ gdbclient "" "" 2508

РЕДАКТИРОВАНИЕ:

Вы по-прежнему можете использовать команду ndk-gdb вместо команды gdbclient,Укажите файлы символов для общих библиотек.

(gdb) set solib-search-path (ANDROID_SOURCE_PATH)/out/target/product/(PRODUCT_NAME)/symbols/system/lib

EDITED 2:

Если вам не нужны символы общих библиотек системы Android, просто adbизвлеките общие библиотеки и установите для него sollib-search-path.

$ adb pull /system/lib lib

$ ndk-gdb
...
(gdb) set solib-search-path lib
4 голосов
/ 15 июня 2011

Пара нот:

  • В некоторых случаях трассировка вашего стека может быть повреждена, поскольку ваш стек был частично уничтожен. Хотя вряд ли.
  • Какую ОС вы используете? Gingerbread (Android 2.3) на 1006 * намного лучше с точки зрения следов стека. Если вы не используете Android 2.3, найдите для своего телефона ПЗУ Android 2.3 или приобретите дешевый телефон для разработчиков под управлением 2.3.
  • Вы видели сценарий Онура ? Это работает очень хорошо для меня, даже на телефонах Android 2.2.
  • Надеюсь, что Фадден это читает, я уверен, что у него есть ответ, который гораздо полезнее моего.
1 голос
/ 18 ноября 2011

Извините, что залил мой собственный вопрос ответами, но я обнаружил, что интеграция Google Breakpad была отличным способом получения хороших стековых трасс / отчетов о сбоях. Легко написать обработчик сигнала, который вызывает Breakpad и обо всем позаботится; нам просто нужно загрузить отчеты на наш сервер. Мы также интегрировали процесс вызова stackwalk.sh в нашу систему сборки. Потребовалась некоторая работа, но в целом она идеально подходит для получения хороших собственных отчетов о сбоях на Android.

Этот ответ содержит некоторые подробности о написании обработчика сигнала; остальной код, который вам нужен, находится на сайте Google Breakpad в вики.

1 голос
/ 27 июня 2011

Проверьте следующий вопрос: Как создать трассировку стека при сбое моего приложения gcc C ++

Мы сделали то же самое с нашим приложением для Android: мы написали наш собственный обработчик сигналов, обработали сигналы 7 (sigbus) и 11 (sigsegv) и распечатали стэк-тэс из обработчика. Хотя мы не использовали функцию backtrace (), но стекали стек вручную ...

Комбинируя первые два ответа, вы сможете написать свой собственный обработчик сигналов для вывода трассировки стека. Эта статья может помочь вам также: http://www.ibm.com/developerworks/power/library/l-sigdebug/index.html. Только помните, что извлечение содержимого регистра зависит от архитектуры, поэтому вы должны заменить структуры, использованные в вышеприведенных кодах, на структуры на Android (в зависимости от процессора ARM). Например, мне пришлось покопаться в источнике Android для «struct ucontext».

Если у вас есть трассировка стека, запустите на выходе сценарий, который разрешит символы с помощью addr2line и вашего необработанного исполняемого файла.

0 голосов
/ 27 июня 2011

Я получил ответ на этот вопрос для некоторых следов стека. (Судя по этому вопросу, это может быть все, что я получаю.) Это те, которые заканчиваются адресом lr (регистр ссылок). Смотрите мой другой вопрос / ответ .

...