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



Моя задача проста:





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



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



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



EDIT



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



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



И стек основного потока, если я установлю обработчик необработанных исключений по умолчанию после того, как исключение будет вызвано.



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

615   2  

2 ответов:

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

Window - > Preferences - > Java - > Debug - > Suspend execution on uncaught exceptions

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

Например

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 на самом деле может перехватывать класс startup вместо вашего пользователя код. Это для регулярного затмения.

Решение 1 :

  1. Goto Run - > Add Java Exception Breakpoint -> Throwable
  2. нажмите на Throwable в представлении точки останова
  3. щелкните правой кнопкой мыши - > Свойства точки останова - > добавить пакет - > OK
  4. проверьте на опции подклассы этого исключения

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

Примечание: это может незначительно поймать java.lang.OutOfMemoryError , но определенно не может поймать a java.lang.StackOverflowError.

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

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

        } catch (Error t) {
            Log.e(TAG, "Error preloading " + line + ".", t);
            throw t;
        }
    
  3. Перейдите к конфигурации отладки - > Classpath - > нажмите Bootstrap Entries - > Add projects - > MyBootstrap. Переместите этот проект наверх

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

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

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

  2. В точке, где происходит перехват исключения, состояние (т. е. кадры стека, переменные и т. д.) Из точки броска ... и вплоть до точки подвоха ... были отброшены.

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


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

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

Comments

    Ничего не найдено.