【问题标题】:thread exiting with uncaught exception: NO stack trace线程以未捕获的异常退出:没有堆栈跟踪
【发布时间】:2012-06-28 19:49:34
【问题描述】:

我的应用程序在某处导致强制关闭,但我的 LogCat 中没有使用通常(而且信息量非常大)堆栈跟踪获得 FATAL EXCEPTION,我只收到以下 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); 实际上并没有打印任何东西。我收到的额外打印来自bogus subclass.uncaughtException(paramThread, paramThrowable);记录完整堆栈跟踪的正确方法是使用Log.e(TAG, "uncaughtException", throwable)

现在剩下的唯一问题是如何重新抛出异常?只需做一个throw paramThrowable

回答我的最后一个问题:Eclipse 不会让我在没有 try/catch 的情况下抛出,这让我明白我想要的不是重新抛出,而是 killProcess()。问题解决了。

【问题讨论】:

  • 也许对你的代码使用 try catch 将有助于识别。
  • @Mukund 我的代码在哪里?我已经在各处使用了大量的 try/catch 子句。
  • 添加一个更通用的 try catch 作为下面的答案,将整个代码包围在一个 .java 文件中。
  • @EternalLearner 与选中的Exceptions 不同,eclipse 让你抛出一个未选中的RuntimeException:就做throw new RuntimeException(paramThrowable);

标签: java android stack-overflow stack-trace uncaught-exception


【解决方案1】:

这将是乏味的,但我会单步执行,直到它与调试器中断。那么你可以添加一个更一般的捕获

捕获(异常 e){ }

所有异常都从 Exception 扩展而来,因此可以帮助您进一步诊断问题。

还有一个想法,也许您的应用正在运行设备内存。由于 JVM 因内存错误而关闭,JVM 可能会在不通知您的情况下杀死您的应用程序。

【讨论】:

  • 感谢 +1 将我的注意力转移到异常消息之前的 GC_FOR_MALLOC 消息。我不认为它是相关的,所以我没有发布它。既然你提到了这种可能性,我更新了我的问题。我会看看你的技术是否适合我。
  • Assylias 在下面的回答比我的要好得多。如果单步执行大型应用程序需要太长时间,则默认异常处理程序是个好主意。
【解决方案2】:

您可以在应用程序的开头设置默认的未捕获异常处理程序并在其中记录一些数据(下面的示例使用 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);
    }
}

【讨论】:

  • 谢谢+1。我可以发誓 Android 已经提供了一个默认的未捕获异常处理程序,但我可能弄错了。我会尽快尝试your approach
  • @EternalLearner 我对 Android 不够熟悉,不知道是不是这样。请参阅this answer to a different question 了解适用于 Android 的类似方法(但可能对您的使用来说太复杂了!)。
  • 您的回答将被接受,因为它显然使我能够在故障排除工作中取得进展。但是,我仍在努力解决一些问题。请参阅上面的更新。 +1。
  • 很好的例子。非常感谢。这个例子帮助我解决了这个问题“线程退出未捕获的异常”。
【解决方案3】:

我知道这是旧的,但如果其他人想知道在处理未捕获的异常后正常退出:

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);
            }
        });

【讨论】:

    猜你喜欢
    • 2012-08-24
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 2014-04-28
    • 1970-01-01
    • 2018-12-03
    • 2013-02-21
    相关资源
    最近更新 更多