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 #include "base/android/java_exception_reporter.h"
6
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/debug/dump_without_crashing.h"
10 #include "jni/JavaExceptionReporter_jni.h"
11
12 using base::android::JavaParamRef;
13
14 namespace base {
15 namespace android {
16
17 namespace {
18
19 void (*g_java_exception_callback)(const char*);
20
21 } // namespace
22
InitJavaExceptionReporter()23 void InitJavaExceptionReporter() {
24 JNIEnv* env = base::android::AttachCurrentThread();
25 constexpr bool crash_after_report = false;
26 Java_JavaExceptionReporter_installHandler(env, crash_after_report);
27 }
28
InitJavaExceptionReporterForChildProcess()29 void InitJavaExceptionReporterForChildProcess() {
30 JNIEnv* env = base::android::AttachCurrentThread();
31 constexpr bool crash_after_report = true;
32 Java_JavaExceptionReporter_installHandler(env, crash_after_report);
33 }
34
SetJavaExceptionCallback(void (* callback)(const char *))35 void SetJavaExceptionCallback(void (*callback)(const char*)) {
36 DCHECK(!g_java_exception_callback);
37 g_java_exception_callback = callback;
38 }
39
SetJavaException(const char * exception)40 void SetJavaException(const char* exception) {
41 // No need to print exception because they are already logged via
42 // env->ExceptionDescribe() within jni_android.cc.
43 if (g_java_exception_callback) {
44 g_java_exception_callback(exception);
45 }
46 }
47
JNI_JavaExceptionReporter_ReportJavaException(JNIEnv * env,const JavaParamRef<jclass> & jcaller,jboolean crash_after_report,const JavaParamRef<jthrowable> & e)48 void JNI_JavaExceptionReporter_ReportJavaException(
49 JNIEnv* env,
50 const JavaParamRef<jclass>& jcaller,
51 jboolean crash_after_report,
52 const JavaParamRef<jthrowable>& e) {
53 std::string exception_info = base::android::GetJavaExceptionInfo(env, e);
54 SetJavaException(exception_info.c_str());
55 if (crash_after_report) {
56 LOG(ERROR) << exception_info;
57 LOG(FATAL) << "Uncaught exception";
58 }
59 base::debug::DumpWithoutCrashing();
60 SetJavaException(nullptr);
61 }
62
JNI_JavaExceptionReporter_ReportJavaStackTrace(JNIEnv * env,const JavaParamRef<jclass> & jcaller,const JavaParamRef<jstring> & stackTrace)63 void JNI_JavaExceptionReporter_ReportJavaStackTrace(
64 JNIEnv* env,
65 const JavaParamRef<jclass>& jcaller,
66 const JavaParamRef<jstring>& stackTrace) {
67 SetJavaException(ConvertJavaStringToUTF8(stackTrace).c_str());
68 base::debug::DumpWithoutCrashing();
69 SetJavaException(nullptr);
70 }
71
72 } // namespace android
73 } // namespace base
74