Eclipse - 在Android App上引发未处理的异常时中断用户代码

chr*_*ini 17 java eclipse debugging android

我的问题很简单:

  • 我使用Ecplise(Luna或Neon)在Android上开发,我不想使用Android Studio

  • 我希望仅在导致异常的堆栈的最后一个用户代码调用上调试所有未处理异常的中断(因此,例如,我不希望在由于引起异常而导致无用的ZygonteInit和MethodAndArgsCaller.run()中断将空引用传递给本机Android SDK方法).

我知道我可以在断点视图中设置一个特定异常的断点(NullPointerException..Throwable ...)但是我希望打破所有未处理的.我知道我可以通过在Java调试选项中设置"步骤过滤器"来过滤调试,但在我的情况下,这不适用于所有异常.

编辑

在调试视图下面的图像下面的图像引发异常时(在我的代码中除以零)

在此输入图像描述

如果我在引发异常后设置了默认的Uncaught Exception Handler,那么主线程的堆栈.

在此输入图像描述

Raj*_*ran 2

您可以首先验证 Eclipse 中的此设置是否已启用。

窗口 -> 首选项 -> Java -> 调试 -> 未捕获异常时暂停执行

如果启用此设置,任何未捕获的异常都将在抛出时挂起 JVM,包括使用反射调用的类。这没有添加任何断点,但提供了未处理的断点,即您的代码甚至没有被 try-catch 中的外部代码调用。

例如

int a = 0, b= 0;
System.out.println(a/b); // ArithmeticException
Run Code Online (Sandbox Code Playgroud)

即使从反射调用代码中调用此代码,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);
            }
Run Code Online (Sandbox Code Playgroud)

此类代码会破坏 Eclipse 调试的原因是,现在不再有未处理RuntimeException的. 您实际上可能正在捕获启动类而不是您的用户代码。这是针对常规 Eclipse 的。UncaughtExceptionHandler

解决方案1:

  1. 转到运行 -> 添加 Java 异常断点 ->Throwable
  2. Throwable在“断点”视图中单击
  3. 右键->断点属性->添加包->确定
  4. 检查此异常的子类选项

在此输入图像描述

注意:这可以勉强捕获 ajava.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;
        }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 转到调试配置 -> 类路径 -> 单击引导条目 -> 添加项目 -> MyBootstrap。将此项目移动到顶部

在此输入图像描述