HwBinder: log exceptions from Java

Before, if there was an uncaught exception from a Java HIDL server,
'Uncaught Exception!' would be printed in logcat, but the actual
exception would only be written to stderr. Now, we use the same binder
functionality to print the error to stdout.

Bug: N/A
Test: manual
Change-Id: I850c3158bad7313013f5e688850ec72cfa2fa686
This commit is contained in:
Steven Moreland
2020-11-17 22:40:20 +00:00
parent aeb15e8592
commit 8f4319d5a7
3 changed files with 19 additions and 20 deletions

View File

@@ -20,6 +20,8 @@
#include "android_os_HwBinder.h"
#include "android_util_Binder.h" // for binder_report_exception
#include "android_os_HwParcel.h"
#include "android_os_HwRemoteBinder.h"
@@ -183,15 +185,7 @@ status_t JHwBinder::onTransact(
env->ExceptionDescribe();
env->ExceptionClear();
// It is illegal to call IsInstanceOf if there is a pending exception.
// Attempting to do so results in a JniAbort which crashes the entire process.
if (env->IsInstanceOf(excep, gErrorClass)) {
/* It's an error */
LOG(ERROR) << "Forcefully exiting";
_exit(1);
} else {
LOG(ERROR) << "Uncaught exception!";
}
binder_report_exception(env, excep, "Uncaught error or exception in hwbinder!");
env->DeleteLocalRef(excep);
}

View File

@@ -302,8 +302,9 @@ static void report_java_lang_error(JNIEnv* env, jthrowable error, const char* ms
report_java_lang_error_fatal_error(env, error, msg);
}
static void report_exception(JNIEnv* env, jthrowable excep, const char* msg)
{
namespace android {
void binder_report_exception(JNIEnv* env, jthrowable excep, const char* msg) {
env->ExceptionClear();
ScopedLocalRef<jstring> tagstr(env, env->NewStringUTF(LOG_TAG));
@@ -331,6 +332,8 @@ static void report_exception(JNIEnv* env, jthrowable excep, const char* msg)
}
}
} // namespace android
class JavaBBinderHolder;
class JavaBBinder : public BBinder
@@ -405,9 +408,9 @@ protected:
if (env->ExceptionCheck()) {
ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
report_exception(env, excep.get(),
"*** Uncaught remote exception! "
"(Exceptions are not yet supported across processes.)");
binder_report_exception(env, excep.get(),
"*** Uncaught remote exception! "
"(Exceptions are not yet supported across processes.)");
res = JNI_FALSE;
}
@@ -421,8 +424,8 @@ protected:
if (env->ExceptionCheck()) {
ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
report_exception(env, excep.get(),
"*** Uncaught exception in onBinderStrictModePolicyChange");
binder_report_exception(env, excep.get(),
"*** Uncaught exception in onBinderStrictModePolicyChange");
}
// Need to always call through the native implementation of
@@ -567,8 +570,8 @@ public:
jBinderProxy.get());
if (env->ExceptionCheck()) {
jthrowable excep = env->ExceptionOccurred();
report_exception(env, excep,
"*** Uncaught exception returned from death notification!");
binder_report_exception(env, excep,
"*** Uncaught exception returned from death notification!");
}
// Serialize with our containing DeathRecipientList so that we can't
@@ -1163,8 +1166,8 @@ static void android_os_BinderInternal_proxyLimitcallback(int uid)
if (env->ExceptionCheck()) {
ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
report_exception(env, excep.get(),
"*** Uncaught exception in binderProxyLimitCallbackFromNative");
binder_report_exception(env, excep.get(),
"*** Uncaught exception in binderProxyLimitCallbackFromNative");
}
}

View File

@@ -35,6 +35,8 @@ extern void set_dalvik_blockguard_policy(JNIEnv* env, jint strict_policy);
extern void signalExceptionForError(JNIEnv* env, jobject obj, status_t err,
bool canThrowRemoteException = false, int parcelSize = 0);
// does not take ownership of the exception, aborts if this is an error
void binder_report_exception(JNIEnv* env, jthrowable excep, const char* msg);
}
#endif