线程退出与未捕获的异常:没有堆栈跟踪

时间:2012-06-27 11:30:29

标签: java android stack-overflow stack-trace uncaught-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

这是在DEBUG模式下,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()。问题解决了。

3 个答案:

答案 0 :(得分:18)

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

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

catch(例外e){ }

所有异常都从Exception扩展,以便可以帮助您进一步诊断您的问题。

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

答案 2 :(得分:0)

我知道这已经过时了,但是如果有其他人想知道在处理未被捕获的例外后正常退出:

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