Подтвердить что ты не робот

Eclipse - прерывать код пользователя, когда необработанное исключение возникает в приложении Android

Моя проблема проста:

  • Я использую Ecplise (Luna или Neon) для разработки на Android, и я не хочу использовать Android Studio

  • Я хочу отлаживать перерывы в ВСЕ необработанных исключениях только при последнем вызове кода пользователя стека, которые вызывают исключение (например, я не хочу прерывать неиспользуемый ZygonteInit & MethodAndArgsCaller.run(), когда исключение вызвано передачей нулевой ссылки на собственный метод Android SDK).

Я знаю, что я могу установить точку прерывания для конкретного исключения в представлении точки останова (NullPointerException..Throwable...), но я хочу, чтобы на ВСЕ все необработанные. Я знаю, что я могу отфильтровывать отладку, устанавливая "фильтры шагов" в опции отладки Java, но в моем случае это не работает для всех исключений.

ИЗМЕНИТЬ

На изображении ниже моего стека в debug View, когда возникает исключение (деление на ноль в моем коде)

введите описание изображения здесь

И стек основного потока, если я устанавливаю обработчик исключения Uncaught по умолчанию после исключения, увеличивается.

введите описание изображения здесь

4b9b3361

Ответ 1

Вы можете сначала проверить, включен ли этот параметр в Eclipse.

Окно → Настройки → Java → Отладка → Приостановить выполнение неперехваченных исключений

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

Например,

int a = 0, b= 0;
System.out.println(a/b); // ArithmeticException

Даже если этот код вызывается из кода, вызванного отражением, eclipse будет приостанавливаться в sysout со всеми переменными, все еще доступными в стеке.

Однако в стартовом классе Android ZygoteInit есть следующая строка:

    catch (Throwable t) {
                Log.e(TAG, "Error preloading " + line + ".", t);
                if (t instanceof Error) {
                    throw (Error) t;
                }
                if (t instanceof RuntimeException) {
                    throw (RuntimeException) t;
                }
                throw new RuntimeException(t);
            }

Причина, по которой такой код нарушает отладку Eclipse, - это RuntimeException теперь не более необработанный. Ваш UncaughtExceptionHandler может фактически поймать класс запуска вместо вашего пользовательского кода. Это для обычного Eclipse.

Решение 1:

  • Перейти к запуску → Добавить точку исключения исключений Java → Throwable
  • Нажмите Throwable в представлении точки останова
  • Щелкните правой кнопкой мыши → Свойства точки останова → Добавить пакет → OK
  • Отметьте опцию Подклассы этого исключения

введите описание изображения здесь

Примечание. Это может незначительно уловить java.lang.OutOfMemoryError, но определенно не может поймать java.lang.StackOverflowError.

Решение 2: (Только если слишком много обнаруженных исключений, НЕ рекомендуемых в противном случае)

  • Скопируйте исходный код com.android.internal.os.ZygoteInit в новый проект: MyBootstrap
  • Измените блок catch (Throwable t), чтобы поймать только Error

        } catch (Error t) {
            Log.e(TAG, "Error preloading " + line + ".", t);
            throw t;
        }
    
  • Настройки отладки → Путь к классам → Нажмите "Загрузки Bootstrap" → Добавить проекты → MyBootstrap. Переместите этот проект в начало

введите описание изображения здесь

Ответ 2

В принципе, если я правильно вас понимаю, вы хотите установить точку останова, которая будет срабатывать в точке, где генерируется исключение, если это исключение не будет/не будет обработано впоследствии.

Если это то, что вы имеете в виду, то то, о чем вы просите, в принципе невозможно.

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

  • В момент, когда исключение поймано, состояние (то есть кадры стека, переменные и т.д.) из точки бросания... и до точки catch... будет отброшено.

  • API-интерфейсы отладчика Java не поддерживают механизм перемотки и повтора, который может использовать отладчик для этого.


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

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