Я перемещаю проект в новый Android Native Development Kit (например, JNI), и я хотел бы поймать SIGSEGV, если это произойдет (возможно, также SIGILL, SIGABRT, SIGFPE), чтобы представить красивый диалог отчета о сбоях вместо (или раньше) то, что происходит в настоящее время: немедленная бесцеремонная смерть процесса и, возможно, некоторая попытка ОС перезапустить его. ( Изменить: виртуальная машина JVM / Dalvik улавливает сигнал и регистрирует трассировку стека и другую полезную информацию; я просто хочу предложить пользователю возможность отправить мне эту информацию по электронной почте.)
Ситуация такова: большая часть кода C, который я не писал, выполняет большую часть работы в этом приложении (всю логику игры), и, хотя он хорошо протестирован на многих других платформах, вполне возможно, что я в моем Android port, будет кормить его мусором и вызвать сбой в собственном коде, поэтому мне нужны аварийные дампы (как собственные, так и Java), которые в настоящее время отображаются в журнале Android (я думаю, что это будет stderr в ситуации, отличной от Android). Я могу произвольно изменять код C и Java, хотя количество обратных вызовов (как входящих, так и исходящих из JNI) составляет около 40 и, очевидно, бонусные баллы за небольшие различия.
Я слышал о библиотеке цепочки сигналов в J2SE, libjsig.so, и если бы я мог безопасно установить такой обработчик сигналов на Android, это решило бы захватывающую часть моего вопроса, но я не вижу такой библиотеки для Android / Dalvik .
Ответы:
Изменить: начиная с Jelly Bean, вы не можете получить трассировку стека, потому что
READ_LOGS
исчезли . :-(У меня действительно есть обработчик сигналов, работающий без каких-либо слишком экзотических действий, и я выпустил код, использующий его, который вы можете увидеть на github (редактировать: ссылка на исторический выпуск; с тех пор я удалил обработчик сбоев). Вот как:
sigaction()
для перехвата сигналов и сохранения старых обработчиков. ( android.c: 570 )startActivity()
действие, которое помечено как требующееся в собственном процессе. ( SGTPuzzles.java:962 , AndroidManifest.xml: 28 )debuggerd
записать для вас хорошую собственную трассировку, а затем процесс прекратит работу. ( debugger.c , debuggerd.c )logcat -d -v threadtime
и запуститеACTION_SEND
с заполненными получателем, темой и телом сообщения. Пользователь должен будет нажать Отправить. ( CrashHandler.java , SGTPuzzles.java:462 , strings.xml: 41logcat
неудач или задержек более нескольких секунд. Я столкнулся с одним устройством, T-Mobile Pulse / Huawei U8220, где logcat сразу переходит вT
(отслеживаемое) состояние и зависает. ( CrashHandler.java:70 , strings.xml : 51 )В ситуации, отличной от Android, кое-что из этого было бы другим. Вам нужно будет собрать свою собственную трассировку, см. Этот другой вопрос , в зависимости от того, какой у вас тип libc. Вам нужно будет обработать сброс этой трассировки, запустить отдельный процесс обработки сбоев и отправить электронное письмо некоторыми способами, подходящими для вашей платформы, но я полагаю, что общий подход все еще должен работать.
источник
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
debuggerd
выходы?Я немного опоздал, но у меня была точно такая же потребность, и я разработал небольшую библиотеку для ее решения, вылавливая общие сбои (
SEGV
,SIBGUS
и т. Д.) Внутри кода JNI и заменяя их обычнымиjava.lang.Error
исключениями. . Бонус: если клиент работает на Android> =4.1.1
, трассировка стека включает разрешенную обратную трассировку сбоя (псевдотрассу, содержащую полную трассировку собственного стека). Вы не сможете оправиться от серьезных сбоев (например, если вы повредите распределитель), но, по крайней мере, это должно позволить вам восстановиться после большинства из них. (пожалуйста, сообщайте об успехах и неудачах, код новый)Дополнительная информация на https://github.com/xroche/coffeecatch (код - лицензия BSD 2-Clauses )
источник
FWIW, Google Breakpad отлично работает на Android. Я выполнил портирование, и мы поставляем его как часть Firefox Mobile. Это требует небольшой настройки, поскольку он не дает вам трассировки стека на стороне клиента, но отправляет вам необработанную память стека и выполняет обход стека на стороне сервера (поэтому вам не нужно отправлять символы отладки с вашим приложением. ).
источник
По моему ограниченному опыту (не Android), SIGSEGV в коде JNI обычно вызывает сбой JVM до того, как управление будет возвращено вашему Java-коду. Я смутно помню, что слышал о какой-то JVM, отличной от Sun, которая позволяет вам ловить SIGSEGV, но AFAICR вы не можете ожидать, что сможете это сделать.
Вы можете попытаться поймать их в C (см. Sigaction (2)), хотя после обработчика SIGSEGV (или SIGFPE, или SIGILL) вы можете сделать очень мало, поскольку текущее поведение процесса официально не определено.
источник
_Unwind_Backtrace
fromunwind.h
.