Skip to content

Commit

Permalink
[monodroid] Prevent a segfault when Java class name is unavailable (#…
Browse files Browse the repository at this point in the history
…5623)

Context: #5619

It appears that Xamarin.Android application uploaded to
Google Play Console internal Test Track can fail the pre-launch test
because the `MonodroidRuntime::get_java_class_name_for_TypeManager()`
method can sometimes get a `nullptr` Java class name from JNI:

	Build fingerprint: 'google/blueline/blueline:9/PQ3A.190801.002/5670241:user/release-keys'
	Revision: 'MP1.0'
	ABI: 'arm64'
	pid: 15773, tid: 15773, name: com.Myapp  >>> com.Myapp<<<
	signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
	Cause: null pointer dereference
	    x0  0000000000000000  x1  0000000000000000  x2  0000000000000000  x3  00000000000000e1
	    x4  0000000000000000  x5  0000000000000305  x6  0000000000000006  x7  0000000000000010
	    x8  0101010101010101  x9  4adfd1b7ed2e23e2  x10 0000000000430000  x11 000000000000000a
	    x12 0000000000000002  x13 0000000000000001  x14 00000000000000a8  x15 000000000000000a
	    x16 0000007f703f00f8  x17 0000007f7031f290  x18 0000000000000008  x19 0000000000000000
	    x20 0000007eecae0460  x21 0000000000000000  x22 0000000000000000  x23 0000000000000099
	    x24 0000000000000085  x25 0000007eecb30010  x26 0000000000000099  x27 0000000000000000
	    x28 0000007f724255e0  x29 0000007fe01ad010
	    sp  0000007fe01acff0  lr  0000007f7036f3b4  pc  0000007f7031f2a0
	backtrace:
	    #00 pc 000000000001e2a0  /system/lib64/libc.so (strlen+16)
	    #1 pc 000000000006e3b0  /system/lib64/libc.so (strdup+20)
	    #2 pc 000000000000d4e8  /data/app/com.Myapp-1lufsJe3FIZ0YHoEAB08KA==/split_config.arm64_v8a.apk (offset 0x165d000) (xamarin::android::internal::MonodroidRuntime::get_java_class_name_for_TypeManager(_jclass*)+92)
	    #3 pc 000000000005f6d0  <anonymous:0000007ecc4ac000>

This can happen if either one of the below points is true:

 1. [`java.lang.Class.getName()`][0] returns `nullptr`
    (a nameless class?  This seems unlikely.)
 2. [`JNIEnv::GetStringUTFChars()`][1] returns `nullptr`
    (a memory allocation failure?)

Of these, (2) appears to be most probable; regardless, add appropriate
`nullptr` checks for each of them, failing gracefully instead of
segfaulting.

This is NOT a fix for the original problem as we don't know by what
it is caused but, nevertheless, the `nullptr` check should be there.

[0]: https://developer.android.com/reference/java/lang/Class?hl=en#getName()
[1]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetStringUTFChars
  • Loading branch information
grendello authored Feb 18, 2021
1 parent 67de0df commit d8df924
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/monodroid/jni/monodroid-glue.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2027,7 +2027,17 @@ MonodroidRuntime::get_java_class_name_for_TypeManager (jclass klass)

JNIEnv *env = osBridge.ensure_jnienv ();
jstring name = reinterpret_cast<jstring> (env->CallObjectMethod (klass, Class_getName));
if (name == nullptr) {
log_error (LOG_DEFAULT, "Failed to obtain Java class name for object at %p", klass);
return nullptr;
}

const char *mutf8 = env->GetStringUTFChars (name, nullptr);
if (mutf8 == nullptr) {
log_error (LOG_DEFAULT, "Failed to convert Java class name to UTF8 (out of memory?)");
env->DeleteLocalRef (name);
return nullptr;
}
char *ret = strdup (mutf8);

env->ReleaseStringUTFChars (name, mutf8);
Expand Down

0 comments on commit d8df924

Please sign in to comment.