Bug 1043457 - Switch Fennec to using CrashHandler; r=snorp

This commit is contained in:
Jim Chen 2014-10-20 16:39:21 -04:00
parent 7567677341
commit 8990545f80
3 changed files with 62 additions and 77 deletions

View File

@ -351,6 +351,7 @@
#if MOZ_CRASHREPORTER
<activity android:name="org.mozilla.gecko.CrashReporter"
android:process="@ANDROID_PACKAGE_NAME@.CrashReporter"
android:label="@string/crash_reporter_title"
android:icon="@drawable/crash_reporter"
android:theme="@style/Gecko"

View File

@ -1125,8 +1125,6 @@ public abstract class GeckoApp
@Override
public void onCreate(Bundle savedInstanceState)
{
GeckoAppShell.registerGlobalExceptionHandler();
// Enable Android Strict Mode for developers' local builds (the "default" channel).
if ("default".equals(AppConstants.MOZ_UPDATE_CHANNEL)) {
enableStrictMode();

View File

@ -14,8 +14,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
@ -129,10 +127,69 @@ public class GeckoAppShell
// We have static members only.
private GeckoAppShell() { }
private static Thread.UncaughtExceptionHandler systemUncaughtHandler;
private static boolean restartScheduled;
private static GeckoEditableListener editableListener;
private static final CrashHandler CRASH_HANDLER = new CrashHandler() {
@Override
protected String getAppPackageName() {
return AppConstants.ANDROID_PACKAGE_NAME;
}
@Override
protected Bundle getCrashExtras(final Thread thread, final Throwable exc,
final Context appContext) {
final Bundle extras = super.getCrashExtras(
thread, exc, sContextGetter != null ? getContext() : null);
extras.putString("ProductName", AppConstants.MOZ_APP_BASENAME);
extras.putString("ProductID", AppConstants.MOZ_APP_ID);
extras.putString("Version", AppConstants.MOZ_APP_VERSION);
extras.putString("BuildID", AppConstants.MOZ_APP_BUILDID);
extras.putString("Vendor", AppConstants.MOZ_APP_VENDOR);
extras.putString("ReleaseChannel", AppConstants.MOZ_UPDATE_CHANNEL);
return extras;
}
@Override
public void uncaughtException(final Thread thread, final Throwable exc) {
if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoExited)) {
// We've called System.exit. All exceptions after this point are Android
// berating us for being nasty to it.
return;
}
super.uncaughtException(thread, exc);
}
@Override
public boolean reportException(final Thread thread, final Throwable exc) {
try {
if (exc instanceof OutOfMemoryError) {
SharedPreferences prefs = getSharedPreferences();
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean(GeckoApp.PREFS_OOM_EXCEPTION, true);
// Synchronously write to disk so we know it's done before we
// shutdown
editor.commit();
}
reportJavaCrash(getExceptionStackTrace(exc));
} catch (final Throwable e) {
}
// reportJavaCrash should have caused us to hard crash. If we're still here,
// it probably means Gecko is not loaded, and we should do something else.
if (AppConstants.MOZ_CRASHREPORTER && AppConstants.MOZILLA_OFFICIAL) {
// Only use Java crash reporter if enabled on official build.
return super.reportException(thread, exc);
}
return false;
}
};
private static final Queue<GeckoEvent> PENDING_EVENTS = new ConcurrentLinkedQueue<GeckoEvent>();
private static final Map<String, String> ALERT_COOKIES = new ConcurrentHashMap<String, String>();
@ -206,27 +263,6 @@ public class GeckoAppShell
public static native void onSurfaceTextureFrameAvailable(Object surfaceTexture, int id);
public static native void dispatchMemoryPressure();
public static void registerGlobalExceptionHandler() {
if (systemUncaughtHandler == null) {
systemUncaughtHandler = Thread.getDefaultUncaughtExceptionHandler();
}
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable e) {
handleUncaughtException(thread, e);
}
});
}
private static String getStackTraceString(Throwable e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
pw.flush();
return sw.toString();
}
private static native void reportJavaCrash(String stackTrace);
public static void notifyUriVisited(String uri) {
@ -415,57 +451,7 @@ public class GeckoAppShell
@WrapElementForJNI(allowMultithread = true, noThrow = true)
public static void handleUncaughtException(Thread thread, Throwable e) {
if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoExited)) {
// We've called System.exit. All exceptions after this point are Android
// berating us for being nasty to it.
return;
}
if (thread == null) {
thread = Thread.currentThread();
}
// If the uncaught exception was rethrown, walk the exception `cause` chain to find
// the original exception so Socorro can correctly collate related crash reports.
Throwable cause;
while ((cause = e.getCause()) != null) {
e = cause;
}
try {
Log.e(LOGTAG, ">>> REPORTING UNCAUGHT EXCEPTION FROM THREAD "
+ thread.getId() + " (\"" + thread.getName() + "\")", e);
Thread mainThread = ThreadUtils.getUiThread();
if (mainThread != null && thread != mainThread) {
Log.e(LOGTAG, "Main thread stack:");
for (StackTraceElement ste : mainThread.getStackTrace()) {
Log.e(LOGTAG, ste.toString());
}
}
if (e instanceof OutOfMemoryError) {
SharedPreferences prefs = getSharedPreferences();
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean(GeckoApp.PREFS_OOM_EXCEPTION, true);
// Synchronously write to disk so we know it's done before we
// shutdown
editor.commit();
}
} catch (final Throwable exc) {
// Report the Java crash below, even if we encounter an exception here.
}
try {
reportJavaCrash(getStackTraceString(e));
} finally {
// reportJavaCrash should have caused us to hard crash. If we're still here,
// it probably means Gecko is not loaded, and we should do something else.
// Bring up the app crashed dialog so we don't crash silently.
if (systemUncaughtHandler != null) {
systemUncaughtHandler.uncaughtException(thread, e);
}
}
CRASH_HANDLER.uncaughtException(thread, e);
}
@WrapElementForJNI