Как я могу поймать SIGSEGV (ошибка сегментации) и получить трассировку стека под JNI на Android?



Answers

Я немного опоздал, но у меня была такая же потребность, и я разработал небольшую библиотеку для решения этой проблемы, поймав общие аварии ( SEGV , SIBGUS и т. Д.) Внутри кода JNI и заменив их обычной java.lang.Error exceptions . Бонус, если клиент работает на Android> = 4.1.1 , трассировка стека включает разрешенную обратную трассу сбоя (псевдотрассировку, содержащую полную собственную трассировку стека). Вы не будете восстанавливаться после порочных сбоев (например, если вы повредите распределитель, например), но по крайней мере это должно позволить вам восстановить большинство из них. (сообщите об успехах и неудачах, код совершенно новый)

Дополнительная информация по адресу https://github.com/xroche/coffeecatch (код - лицензия BSD 2-Clauses )

Question

Я перемещаю проект в новый Android Native Development Kit (т. Е. JNI), и я бы хотел поймать SIGSEGV, если это произойдет (возможно, SIGILL, SIGABRT, SIGFPE), чтобы представить хороший диалог отчетов о сбоях, а не (или раньше), что в настоящее время происходит: немедленная бесцеремонная смерть процесса и, возможно, некоторые попытки ОС перезапустить его. ( Редактировать: JVM / Dalvik VM захватывает сигнал и записывает трассировку стека и другую полезную информацию, я просто хочу предложить пользователю возможность отправить мне эту информацию по электронной почте.)

Ситуация такова: большой объем кода C, который я не писал, делает большую часть работы в этом приложении (все логики игры), и хотя он хорошо протестирован на многих других платформах, вполне возможно, что я, на своем Android порт, будет кормить его мусором и вызвать сбой в собственном коде, поэтому мне нужны дампы сбоя (как родные, так и Java), которые в настоящее время отображаются в журнале Android (я думаю, это будет stderr в ситуации, отличной от Android). Я могу свободно изменять код C и Java произвольно, хотя обратные вызовы (как входящие, так и выходящие из JNI) насчитывают около 40 и, очевидно, бонусные баллы для небольших различий.

Я слышал о библиотеке цепочек сигналов в J2SE, libjsig.so, и если бы я мог безопасно установить обработчик сигнала, подобный этому на Android, это решило бы ловушку моего вопроса, но я не вижу такой библиотеки для Android / Dalvik ,




В моем ограниченном опыте (не Android), SIGSEGV в коде JNI, как правило, приводит к сбою JVM до того, как элемент управления будет возвращен вашему Java-коду. Я смутно помню, как слышал о некоторых не-Sun JVM, которые позволяют вам поймать SIGSEGV, но AFAICR вы не можете ожидать, что сможете это сделать.

Вы можете попытаться поймать их на C (см. Sigaction (2)), хотя вы можете сделать очень мало после обработчика SIGSEGV (или SIGFPE или SIGILL), поскольку текущее поведение процесса официально не определено.






Links