diff options
| -rw-r--r-- | core/java/com/android/internal/os/RuntimeInit.java | 61 | ||||
| -rw-r--r-- | preloaded-classes | 3 |
2 files changed, 44 insertions, 20 deletions
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java index 3b8b7cb2ba2f..ff81bc67f7a8 100644 --- a/core/java/com/android/internal/os/RuntimeInit.java +++ b/core/java/com/android/internal/os/RuntimeInit.java @@ -62,30 +62,49 @@ public class RuntimeInit { } /** - * Use this to log a message when a thread exits due to an uncaught - * exception. The framework catches these for the main threads, so - * this should only matter for threads created by applications. + * Logs a message when a thread encounters an uncaught exception. By + * default, {@link KillApplicationHandler} will terminate this process later, + * but apps can override that behavior. */ - private static class UncaughtHandler implements Thread.UncaughtExceptionHandler { + private static class LoggingHandler implements Thread.UncaughtExceptionHandler { + @Override + public void uncaughtException(Thread t, Throwable e) { + // Don't re-enter if KillApplicationHandler has already run + if (mCrashing) return; + if (mApplicationObject == null) { + // The "FATAL EXCEPTION" string is still used on Android even though + // apps can set a custom UncaughtExceptionHandler that renders uncaught + // exceptions non-fatal. + Clog_e(TAG, "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e); + } else { + StringBuilder message = new StringBuilder(); + // The "FATAL EXCEPTION" string is still used on Android even though + // apps can set a custom UncaughtExceptionHandler that renders uncaught + // exceptions non-fatal. + message.append("FATAL EXCEPTION: ").append(t.getName()).append("\n"); + final String processName = ActivityThread.currentProcessName(); + if (processName != null) { + message.append("Process: ").append(processName).append(", "); + } + message.append("PID: ").append(Process.myPid()); + Clog_e(TAG, message.toString(), e); + } + } + } + + /** + * Handle application death from an uncaught exception. The framework + * catches these for the main threads, so this should only matter for + * threads created by applications. Before this method runs, + * {@link LoggingHandler} will already have logged details. + */ + private static class KillApplicationHandler implements Thread.UncaughtExceptionHandler { public void uncaughtException(Thread t, Throwable e) { try { // Don't re-enter -- avoid infinite loops if crash-reporting crashes. if (mCrashing) return; mCrashing = true; - if (mApplicationObject == null) { - Clog_e(TAG, "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e); - } else { - StringBuilder message = new StringBuilder(); - message.append("FATAL EXCEPTION: ").append(t.getName()).append("\n"); - final String processName = ActivityThread.currentProcessName(); - if (processName != null) { - message.append("Process: ").append(processName).append(", "); - } - message.append("PID: ").append(Process.myPid()); - Clog_e(TAG, message.toString(), e); - } - // Try to end profiling. If a profiler is running at this point, and we kill the // process (below), the in-memory buffer will be lost. So try to stop, which will // flush the buffer. (This makes method trace profiling useful to debug crashes.) @@ -113,8 +132,12 @@ public class RuntimeInit { private static final void commonInit() { if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!"); - /* set default handler; this applies to all threads in the VM */ - Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler()); + /* + * set handlers; these apply to all threads in the VM. Apps can replace + * the default handler, but not the pre handler. + */ + Thread.setUncaughtExceptionPreHandler(new LoggingHandler()); + Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler()); /* * Install a TimezoneGetter subclass for ZoneInfo.db diff --git a/preloaded-classes b/preloaded-classes index 8e8faf463a94..cd146f1642e2 100644 --- a/preloaded-classes +++ b/preloaded-classes @@ -2257,7 +2257,8 @@ com.android.internal.os.LoggingPrintStream$1 com.android.internal.os.RuntimeInit com.android.internal.os.RuntimeInit$1 com.android.internal.os.RuntimeInit$Arguments -com.android.internal.os.RuntimeInit$UncaughtHandler +com.android.internal.os.RuntimeInit$KillApplicationHandler +com.android.internal.os.RuntimeInit$LoggingHandler com.android.internal.os.SamplingProfilerIntegration com.android.internal.os.SomeArgs com.android.internal.os.Zygote |