1 // Copyright 2015 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.base; 6 7 import android.support.annotation.UiThread; 8 9 import org.chromium.base.annotations.CalledByNative; 10 import org.chromium.base.annotations.JNINamespace; 11 import org.chromium.base.annotations.MainDex; 12 13 /** 14 * This UncaughtExceptionHandler will create a breakpad minidump when there is an uncaught 15 * exception. 16 * 17 * The exception's stack trace will be added to the minidump's data. This allows java-only crashes 18 * to be reported in the same way as other native crashes. 19 */ 20 @JNINamespace("base::android") 21 @MainDex 22 public class JavaExceptionReporter implements Thread.UncaughtExceptionHandler { 23 private final Thread.UncaughtExceptionHandler mParent; 24 private final boolean mCrashAfterReport; 25 private boolean mHandlingException; 26 JavaExceptionReporter( Thread.UncaughtExceptionHandler parent, boolean crashAfterReport)27 private JavaExceptionReporter( 28 Thread.UncaughtExceptionHandler parent, boolean crashAfterReport) { 29 mParent = parent; 30 mCrashAfterReport = crashAfterReport; 31 } 32 33 @Override uncaughtException(Thread t, Throwable e)34 public void uncaughtException(Thread t, Throwable e) { 35 if (!mHandlingException) { 36 mHandlingException = true; 37 nativeReportJavaException(mCrashAfterReport, e); 38 } 39 if (mParent != null) { 40 mParent.uncaughtException(t, e); 41 } 42 } 43 44 /** 45 * Report and upload the stack trace as if it was a crash. This is very expensive and should 46 * be called rarely and only on the UI thread to avoid corrupting other crash uploads. Ideally 47 * only called in idle handlers. 48 * 49 * @param stackTrace The stack trace to report. 50 */ 51 @UiThread reportStackTrace(String stackTrace)52 public static void reportStackTrace(String stackTrace) { 53 assert ThreadUtils.runningOnUiThread(); 54 nativeReportJavaStackTrace(stackTrace); 55 } 56 57 @CalledByNative installHandler(boolean crashAfterReport)58 private static void installHandler(boolean crashAfterReport) { 59 Thread.setDefaultUncaughtExceptionHandler(new JavaExceptionReporter( 60 Thread.getDefaultUncaughtExceptionHandler(), crashAfterReport)); 61 } 62 nativeReportJavaException(boolean crashAfterReport, Throwable e)63 private static native void nativeReportJavaException(boolean crashAfterReport, Throwable e); nativeReportJavaStackTrace(String stackTrace)64 private static native void nativeReportJavaStackTrace(String stackTrace); 65 } 66