summaryrefslogtreecommitdiffstats
path: root/base/android/jni_android.cc
diff options
context:
space:
mode:
authornileshagrawal@chromium.org <nileshagrawal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-23 05:59:49 +0000
committernileshagrawal@chromium.org <nileshagrawal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-23 05:59:49 +0000
commit1b46a53709a9210b0f72bdd297343c07dcc6d71c (patch)
treecf2f01360d4e91d79deceffc224ccff8721fa255 /base/android/jni_android.cc
parent299d7f1d0003d467a159fb79ba1884080a655a00 (diff)
downloadchromium_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.cc66
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