diff options
author | nileshagrawal@chromium.org <nileshagrawal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-23 05:59:49 +0000 |
---|---|---|
committer | nileshagrawal@chromium.org <nileshagrawal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-23 05:59:49 +0000 |
commit | 1b46a53709a9210b0f72bdd297343c07dcc6d71c (patch) | |
tree | cf2f01360d4e91d79deceffc224ccff8721fa255 /base/android/jni_android.cc | |
parent | 299d7f1d0003d467a159fb79ba1884080a655a00 (diff) | |
download | chromium_src-1b46a53709a9210b0f72bdd297343c07dcc6d71c.zip chromium_src-1b46a53709a9210b0f72bdd297343c07dcc6d71c.tar.gz chromium_src-1b46a53709a9210b0f72bdd297343c07dcc6d71c.tar.bz2 |
Add java exception information to BuildInfo.
This information will be read by breakpad during minidump preparation to
upload any java stack trace.
BUG=
TEST=
Review URL: https://chromiumcodereview.appspot.com/10412045
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@138435 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/android/jni_android.cc')
-rw-r--r-- | base/android/jni_android.cc | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/base/android/jni_android.cc b/base/android/jni_android.cc index 1b7c72c8..2a01063 100644 --- a/base/android/jni_android.cc +++ b/base/android/jni_android.cc @@ -6,12 +6,17 @@ #include <map> +#include "base/android/build_info.h" +#include "base/android/jni_string.h" #include "base/atomicops.h" #include "base/lazy_instance.h" #include "base/logging.h" #include "base/threading/platform_thread.h" namespace { +using base::android::GetClass; +using base::android::GetMethodID; +using base::android::ScopedJavaLocalRef; JavaVM* g_jvm = NULL; @@ -49,7 +54,48 @@ const base::subtle::AtomicWord kUnlocked = 0; const base::subtle::AtomicWord kLocked = 1; base::subtle::AtomicWord g_method_id_map_lock = kUnlocked; +std::string GetJavaExceptionInfo(JNIEnv* env, jthrowable java_throwable) { + ScopedJavaLocalRef<jclass> throwable_clazz = + GetClass(env, "java/lang/Throwable"); + jmethodID throwable_printstacktrace = + GetMethodID(env, throwable_clazz, "printStackTrace", + "(Ljava/io/PrintStream;)V"); + + // Create an instance of ByteArrayOutputStream. + ScopedJavaLocalRef<jclass> bytearray_output_stream_clazz = + GetClass(env, "java/io/ByteArrayOutputStream"); + jmethodID bytearray_output_stream_constructor = + GetMethodID(env, bytearray_output_stream_clazz, "<init>", "()V"); + jmethodID bytearray_output_stream_tostring = + GetMethodID(env, bytearray_output_stream_clazz, "toString", + "()Ljava/lang/String;"); + ScopedJavaLocalRef<jobject> bytearray_output_stream(env, + env->NewObject(bytearray_output_stream_clazz.obj(), + bytearray_output_stream_constructor)); + + // Create an instance of PrintStream. + ScopedJavaLocalRef<jclass> printstream_clazz = + GetClass(env, "java/io/PrintStream"); + jmethodID printstream_constructor = + GetMethodID(env, printstream_clazz, "<init>", + "(Ljava/io/OutputStream;)V"); + ScopedJavaLocalRef<jobject> printstream(env, + env->NewObject(printstream_clazz.obj(), printstream_constructor, + bytearray_output_stream.obj())); + + // Call Throwable.printStackTrace(PrintStream) + env->CallVoidMethod(java_throwable, throwable_printstacktrace, + printstream.obj()); + + // Call ByteArrayOutputStream.toString() + ScopedJavaLocalRef<jstring> exception_string( + env, static_cast<jstring>( + env->CallObjectMethod(bytearray_output_stream.obj(), + bytearray_output_stream_tostring))); + + return ConvertJavaStringToUTF8(exception_string); } +} // namespace namespace base { namespace android { @@ -250,15 +296,31 @@ bool HasException(JNIEnv* env) { bool ClearException(JNIEnv* env) { if (!HasException(env)) return false; + env->ExceptionDescribe(); env->ExceptionClear(); return true; } void CheckException(JNIEnv* env) { - if (HasException(env)) { - env->ExceptionDescribe(); + if (!HasException(env)) return; + + // Ugh, we are going to die, might as well tell breakpad about it. + jthrowable java_throwable = env->ExceptionOccurred(); + if (!java_throwable) { + // Nothing we can do. CHECK(false); } + + // Clear the pending exception, we do have a reference to it. + env->ExceptionClear(); + + // Set the exception_string in BuildInfo so that breakpad can read it. + // RVO should avoid any extra copies of the exception string. + base::android::BuildInfo::GetInstance()->set_java_exception_info( + GetJavaExceptionInfo(env, java_throwable)); + + // Now, feel good about it and die. + CHECK(false); } } // namespace android |