Merge "Ensure apps cannot prevent uncaught exceptions being logged."

am: f61a449ee9

Change-Id: I826c175547a73123cd438ebe6991efee39a433d0
This commit is contained in:
Tobias Thierer
2016-08-09 09:02:27 +00:00
committed by android-build-merger
2 changed files with 44 additions and 20 deletions

View File

@@ -62,21 +62,25 @@ public class RuntimeInit {
} }
/** /**
* Use this to log a message when a thread exits due to an uncaught * Logs a message when a thread encounters an uncaught exception. By
* exception. The framework catches these for the main threads, so * default, {@link KillApplicationHandler} will terminate this process later,
* this should only matter for threads created by applications. * 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) { public void uncaughtException(Thread t, Throwable e) {
try { // Don't re-enter if KillApplicationHandler has already run
// Don't re-enter -- avoid infinite loops if crash-reporting crashes.
if (mCrashing) return; if (mCrashing) return;
mCrashing = true;
if (mApplicationObject == null) { 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); Clog_e(TAG, "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e);
} else { } else {
StringBuilder message = new StringBuilder(); 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"); message.append("FATAL EXCEPTION: ").append(t.getName()).append("\n");
final String processName = ActivityThread.currentProcessName(); final String processName = ActivityThread.currentProcessName();
if (processName != null) { if (processName != null) {
@@ -85,6 +89,21 @@ public class RuntimeInit {
message.append("PID: ").append(Process.myPid()); message.append("PID: ").append(Process.myPid());
Clog_e(TAG, message.toString(), e); 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;
// Try to end profiling. If a profiler is running at this point, and we kill the // 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 // process (below), the in-memory buffer will be lost. So try to stop, which will
@@ -117,8 +136,12 @@ public class RuntimeInit {
private static final void commonInit() { private static final void commonInit() {
if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!"); 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 * Install a TimezoneGetter subclass for ZoneInfo.db

View File

@@ -2540,7 +2540,8 @@ com.android.internal.os.PathClassLoaderFactory
com.android.internal.os.RuntimeInit com.android.internal.os.RuntimeInit
com.android.internal.os.RuntimeInit$1 com.android.internal.os.RuntimeInit$1
com.android.internal.os.RuntimeInit$Arguments 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.SamplingProfilerIntegration
com.android.internal.os.SomeArgs com.android.internal.os.SomeArgs
com.android.internal.os.Zygote com.android.internal.os.Zygote