поток завершается с необработанным исключением: НЕТ трассировки стека

Мое приложение вызывает принудительное закрытие где-то, но вместо того, чтобы получить FATAL EXCEPTION с обычной (и очень информативной) трассировкой стека в моем LogCat, я получаю только следующие 4 строки:

06-27 07:08:54.546: D/dalvikvm(14351): GC_FOR_MALLOC freed 9923 objects / 657416 bytes in 21ms
06-27 07:08:54.769: W/dalvikvm(14351): threadid=20: thread exiting with uncaught exception (group=0x4001d7f0)
06-27 07:08:54.796: W/dalvikvm(14351): threadid=21: thread exiting with uncaught exception (group=0x4001d7f0)
06-27 07:08:54.796: I/Process(14351): Sending signal. PID: 14351 SIG: 9

Это в режиме ОТЛАДКИ без применения ФИЛЬТРОВ к LogCat!

  • Что может быть причиной такого поведения?
  • Есть ли способ узнать, что вызывает это исключение?

Обновление: благодаря @assylias ниже я смог реализовать:

final UncaughtExceptionHandler subclass = Thread.currentThread().getUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
    Log.getStackTraceString(paramThrowable);

    subclass.uncaughtException(paramThread, paramThrowable);
    }
});

Что произвело эти добавленные строки:

06-27 08:24:47.105: D/dalvikvm(15475): GC_FOR_MALLOC freed 13865 objects / 1435952 bytes in 45ms
06-27 08:24:47.136: I/dalvikvm(15475): threadid=15: stack overflow on call to Ljava/lang/AbstractStringBuilder;.enlargeBuffer:VI
06-27 08:24:47.136: I/dalvikvm(15475):   method requires 28+20+20=68 bytes, fp is 0x45209338 (56 left)
06-27 08:24:47.140: I/dalvikvm(15475):   expanding stack end (0x45209300 to 0x45209000)
06-27 08:24:47.140: I/dalvikvm(15475): Shrank stack (to 0x45209300, curFrame is 0x4520937c)
06-27 08:24:47.159: I/dalvikvm(15475): threadid=16: stack overflow on call to Ljava/lang/AbstractStringBuilder;.enlargeBuffer:VI
06-27 08:24:47.159: I/dalvikvm(15475):   method requires 28+20+20=68 bytes, fp is 0x4520c338 (56 left)
06-27 08:24:47.167: I/dalvikvm(15475):   expanding stack end (0x4520c300 to 0x4520c000)
06-27 08:24:47.167: I/dalvikvm(15475): Shrank stack (to 0x4520c300, curFrame is 0x4520c37c)
06-27 08:24:47.175: I/dalvikvm(15475): threadid=17: stack overflow on call to Ljava/lang/AbstractStringBuilder;.enlargeBuffer:VI
06-27 08:24:47.175: I/dalvikvm(15475):   method requires 28+20+20=68 bytes, fp is 0x4520f338 (56 left)
06-27 08:24:47.175: I/dalvikvm(15475):   expanding stack end (0x4520f300 to 0x4520f000)
06-27 08:24:47.175: I/dalvikvm(15475): Shrank stack (to 0x4520f300, curFrame is 0x4520f37c)

Это, безусловно, гораздо более полезная информация, но сейчас я борюсь со следующим:

  • Приложение не закрывается принудительно, несмотря на вызов subclass.uncaughtException(). Почему?
  • В чем смысл всех этих переполнений стека? Что я мог делать, что так утомительно для моего бедного тестового устройства Android?
  • Как я могу определить, какая часть моего кода вызывает это?

Обновление: Log.getStackTraceString(paramThrowable); на самом деле ничего не печатал. Дополнительный отпечаток, который я получил, был от фиктивного subclass.uncaughtException(paramThread, paramThrowable); Правильный способ регистрации полной трассировки стека — использовать Log.e(TAG, "uncaughtException", throwable).

Остался только один вопрос: как повторно выдать исключение? Просто сделать throw paramThrowable?

Отвечая на мой последний вопрос: Eclipse не позволит мне бросить без окружения с помощью try/catch, что привело меня к пониманию, что я хочу не повторного броска, а killProcess(). Проблема решена.


person Eternal Learner    schedule 27.06.2012    source источник
comment
Возможно, использование try catch для вашего кода поможет идентифицировать.   -  person Mukund Samant    schedule 27.06.2012
comment
@Mukund Где в моем коде? Я уже повсеместно использую многочисленные предложения try/catch.   -  person Eternal Learner    schedule 27.06.2012
comment
Добавьте более общую попытку catch в качестве ответа ниже, окружающего весь код в файле .java.   -  person Mukund Samant    schedule 27.06.2012
comment
@EternalLearner, в отличие от проверенных Exception, eclipse позволит выдать непроверенный RuntimeException: просто сделайте throw new RuntimeException(paramThrowable);   -  person Nolan Amy    schedule 15.05.2014


Ответы (3)


Вы можете установить обработчик необработанных исключений по умолчанию в начале вашего приложения и записать туда некоторые данные (в приведенном ниже примере используется регистратор Java, но его легко перенести на Android):

private static void setDefaultUncaughtExceptionHandler() {
    try {
        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {

            @Override
            public void uncaughtException(Thread t, Throwable e) {
                logger.error("Uncaught Exception detected in thread {}", t, e);
            }
        });
    } catch (SecurityException e) {
        logger.error("Could not set the Default Uncaught Exception Handler", e);
    }
}
person assylias    schedule 27.06.2012
comment
Спасибо +1. Я мог бы поклясться, что Android уже предоставляет обработчик необработанных исключений по умолчанию, но я могу ошибаться. В ближайшее время я попробую ваш подход. - person Eternal Learner; 27.06.2012
comment
@EternalLearner Я недостаточно знаком с Android, чтобы знать, так ли это. См. этот ответ на другой вопрос для аналогичного подхода, примененного к Android (но, вероятно, слишком сложного для вашего использования!). - person assylias; 27.06.2012
comment
Ваш ответ будет принят, потому что он явно позволил мне добиться прогресса в моих усилиях по устранению неполадок. Тем не менее, я все еще борюсь с некоторыми проблемами. Смотрите мое обновление выше. +1. - person Eternal Learner; 27.06.2012
comment
Отличный пример. Большое спасибо. Этот пример помог мне решить эту проблему, выходящую из потока с необработанным исключением. - person Prosanto; 23.07.2014

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

поймать (Исключение д) { }

Все исключения распространяются на Exception, что может помочь вам в дальнейшей диагностике вашей проблемы.

Еще одна идея, возможно, ваше приложение использует память устройства. JVM может убить ваше приложение, не сообщая вам об этом, из-за отключения JVM из-за ошибки памяти.

person Ryan Gray    schedule 27.06.2012
comment
Спасибо +1 за то, что обратил мое внимание на это сообщение GC_FOR_MALLOC прямо перед сообщениями об исключениях. Я не думал, что это актуально, поэтому я не разместил его. Теперь, когда вы упомянули об этой возможности, я обновил свой вопрос. Я посмотрю, сработает ли ваша методика для меня. - person Eternal Learner; 27.06.2012
comment
Ответ Ассилиаса внизу намного лучше моего. обработчики исключений по умолчанию — хорошая идея, если однократное прохождение большого приложения займет слишком много времени. - person Ryan Gray; 27.06.2012

Я знаю, что это старо, но если кто-то еще хочет знать о выходе в обычном режиме после обработки неперехваченного исключения:

final Thread.UncaughtExceptionHandler androidDefaultUEH = Thread.getDefaultUncaughtExceptionHandler();

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(final Thread thread, final Throwable ex) {
                // Handle exception however you want, then:
                androidDefaultUEH.uncaughtException(thread, ex);
            }
        });
person nasch    schedule 28.07.2017