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

Вы абсолютно правы, поддержка взаимодействия с сервером без сохранения состояния создает дополнительную нагрузку на клиента. Однако, если вы подумаете о масштабировании приложения, вычислительная мощность клиентов прямо пропорциональна количеству клиентов. Поэтому масштабирование на большое количество клиентов гораздо более осуществимо.

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

Это компромисс.

90
задан Chris Boyle 9 April 2010 в 15:52
поделиться

2 ответа

Редактировать: Начиная с Jelly Bean, вы не можете получить трассировку стека, потому что READ_LOGS исчезли . : - (

У меня действительно есть обработчик сигналов, работающий без каких-либо слишком экзотических действий, и я выпустил код, использующий его, который вы можете увидеть на github (правка: ссылка на исторический выпуск; я удалил сбой обработчик с тех пор). Вот как:

  1. Используйте sigaction () , чтобы перехватить сигналы и сохранить старые обработчики. ( android.c: 570 )
  2. Время идет, происходит segfault.
  3. В обработчике сигнала вызовите JNI в последний раз, а затем вызовите старый обработчик. ( android.c: 528 )
  4. В этом вызове JNI регистрируйте все полезные информация об отладке и вызов startActivity () для действия, которое помечено как требующее выполнения в собственном процессе. ( SGTPuzzles.java:962 , AndroidManifest.xml: 28 )
  5. Когда вы вернетесь с Java и вызовете этот старый обработчик, платформа Android подключится к debuggerd , чтобы записать для вас красивую собственную трассировку, и тогда процесс завершится. ( debugger.c , debuggerd.c )
  6. Тем временем ваша деятельность по обработке сбоев начинается. На самом деле вы должны передать ему PID, чтобы он мог дождаться завершения шага 5; Я этого не делаю. Здесь вы извиняетесь перед пользователем и спрашиваете, можете ли вы отправить лог. Если это так, соберите вывод logcat -d -v threadtime и запустите ACTION_SEND с заполненными получателем, темой и телом сообщения. Пользователь должен будет нажать Отправить. ( CrashHandler.java , SGTPuzzles.java:462 , strings.xml: 41
  7. Обратите внимание на то, что logcat не сработает или не займет более нескольких секунд. Я столкнулся с одним устройством, T-Mobile Pulse / Huawei U8220, где logcat сразу переходит в состояние T (отслеживается) и зависает. ( CrashHandler.java:70 , strings.xml: 51 )

В ситуации, отличной от Android, некоторые из них будут другими. Вам нужно будет собрать свою собственную трассировку, см. этот другой вопрос , в зависимости от того, какой у вас тип libc. Вам нужно будет обработать сброс этой трассировки, запустить отдельный процесс обработки сбоев и отправить электронное письмо некоторыми способами, подходящими для вашей платформы, но я полагаю, что общий подход все равно должен работать.

T-Mobile Pulse / Huawei U8220, где logcat немедленно переходит в состояние T (отслеживается) и зависает. ( CrashHandler.java:70 , strings.xml: 51 )

В ситуации, отличной от Android, некоторые из них будут другими. Вам нужно будет собрать свою собственную трассировку, см. этот другой вопрос , в зависимости от того, какой у вас тип libc. Вам нужно будет обработать дамп этой трассировки, запустить отдельный процесс обработки сбоев и отправить электронное письмо некоторыми способами, подходящими для вашей платформы, но я полагаю, что общий подход все равно должен работать.

T-Mobile Pulse / Huawei U8220, где logcat немедленно переходит в состояние T (отслеживается) и зависает. ( CrashHandler.java:70 , strings.xml: 51 )

В ситуации, отличной от Android, некоторые из них будут другими. Вам нужно будет собрать свою собственную трассировку, см. этот другой вопрос , в зависимости от того, какой у вас тип libc. Вам нужно будет обработать сброс этой трассировки, запустить отдельный процесс обработки сбоев и отправить электронное письмо некоторыми способами, подходящими для вашей платформы, но я полагаю, что общий подход все равно должен работать.

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

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

81
ответ дан 24 November 2019 в 07:07
поделиться

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

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

5
ответ дан 24 November 2019 в 07:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: