Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"CallStaticIntMethodV received NULL jclass" in _monodroid_get_identity_hash_code() when using DX and multidex #4570

Closed
brendanzagaeski opened this issue Apr 17, 2020 · 9 comments
Assignees
Labels
Area: App Runtime Issues in `libmonodroid.so`. need-info Issues that need more information from the author.

Comments

@brendanzagaeski
Copy link
Member

brendanzagaeski commented Apr 17, 2020

This is a new report to discuss the behavior from #4486 (comment).

Steps to reproduce

Not yet known precisely. The original scenario from #4486 involved building with:

  • Xamarin.Android 10.2.0.100 (d16-5)
  • Release configuration
  • Multidex enabled
  • DX DEX compiler
  • Android App Bundle publishing format
  • $(AndroidLinkMode)=SdkOnly
  • $(AndroidSupportedAbis)=armeabi-v7a;arm64-v8a;x86_64;x86
  • $(AotAssemblies)=False
  • $(AndroidAotMode)=None
  • $(AndroidEnableProguard) not set

The specific emulator image might also be relevant. I haven't yet seen the issue myself locally on an x86 emulator, but there might be some specifics of the emulator image or app configuration I'm missing.

Actual behavior

Extracted error from the logcat output in #4486 (comment):

JNI DETECTED ERROR IN APPLICATION: CallStaticIntMethodV received NULL jclass
    in call to CallStaticIntMethodV
    from void mono.android.Runtime.initInternal(java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.ClassLoader, java.lang.String[], java.lang.String[], int, boolean, boolean)
"main" prio=5 tid=1 Runnable
  | group="main" sCount=0 dsCount=0 flags=0 obj=0x74634760 self=0xeba5d000
  | sysTid=23088 nice=-10 cgrp=default sched=0/0 handle=0xf06d4494
  | state=R schedstat=( 667268385 365640277 294 ) utm=43 stm=23 core=0 HZ=100
  | stack=0xff0dd000-0xff0df000 stackSize=8MB
  | held mutexes= "mutator lock"(shared held)
  native: #00 pc 004151b6  /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+198)
  native: #01 pc 0051034e  /system/lib/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, bool, BacktraceMap*, bool) const+382)
  native: #02 pc 0050b603  /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, bool, BacktraceMap*, bool) const+83)
  native: #03 pc 0031a720  /system/lib/libart.so (art::JavaVMExt::JniAbort(char const*, char const*)+1088)
  native: #04 pc 0031ab91  /system/lib/libart.so (art::JavaVMExt::JniAbortV(char const*, char const*, char*)+113)
  native: #05 pc 000d5f77  /system/lib/libart.so (art::(anonymous namespace)::ScopedCheck::AbortF(char const*, ...)+71)
  native: #06 pc 000d53a0  /system/lib/libart.so (art::(anonymous namespace)::ScopedCheck::CheckInstance(art::ScopedObjectAccess&, art::(anonymous namespace)::ScopedCheck::InstanceKind, _jobject*, bool)+96)
  native: #07 pc 000d4637  /system/lib/libart.so (art::(anonymous namespace)::ScopedCheck::CheckPossibleHeapValue(art::ScopedObjectAccess&, char, art::(anonymous namespace)::JniValueType)+551)
  native: #08 pc 000d3a5b  /system/lib/libart.so (art::(anonymous namespace)::ScopedCheck::Check(art::ScopedObjectAccess&, bool, char const*, art::(anonymous namespace)::JniValueType*)+811)
  native: #09 pc 000d9758  /system/lib/libart.so (art::(anonymous namespace)::CheckJNI::CheckCallArgs(art::ScopedObjectAccess&, art::(anonymous namespace)::ScopedCheck&, _JNIEnv*, _jobject*, _jclass*, _jmethodID*, art::InvokeType, art::(anonymous namespace)::VarArgs const*)+200)
  native: #10 pc 000d8974  /system/lib/libart.so (art::(anonymous namespace)::CheckJNI::CallMethodV(char const*, _JNIEnv*, _jobject*, _jclass*, _jmethodID*, char*, art::Primitive::Type, art::InvokeType)+948)
  native: #11 pc 000c6659  /system/lib/libart.so (art::(anonymous namespace)::CheckJNI::CallStaticIntMethodV(_JNIEnv*, _jclass*, _jmethodID*, char*)+73)
  native: #12 pc 0000b57e  /data/app/it.arcasgr.apparcafondi-puSgzkG14B3kAjDQgAy2cQ==/split_config.x86.apk (offset 3a1000) (_JNIEnv::CallStaticIntMethod(_jclass*, _jmethodID*, ...)+62)
  native: #13 pc 0000b52c  /data/app/it.arcasgr.apparcafondi-puSgzkG14B3kAjDQgAy2cQ==/split_config.x86.apk (offset 3a1000) (_monodroid_get_identity_hash_code+44)
  native: #14 pc 0000037b  <anonymous:e7fb7000> (???)
  at mono.android.Runtime.initInternal(Native method)
  at mono.MonoPackageManager.LoadApplication(MonoPackageManager.java:83)
  - locked <0x04753a2a> (a java.lang.Object)
  at mono.MonoRuntimeProvider.attachInfo(MonoRuntimeProvider.java:35)
  at android.app.ActivityThread.installProvider(ActivityThread.java:6391)
  at android.app.ActivityThread.installContentProviders(ActivityThread.java:5938)
  at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5853)
  at android.app.ActivityThread.access$1100(ActivityThread.java:199)
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1650)
  at android.os.Handler.dispatchMessage(Handler.java:106)
  at android.os.Looper.loop(Looper.java:193)
  at android.app.ActivityThread.main(ActivityThread.java:6669)
  at java.lang.reflect.Method.invoke(Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Initial notes

It seems get_class_from_runtime_field() might be returning nullptr when it tries to look up the java.lang.System type to pass to monodroidRuntime.get_java_class_System ()?

_monodroid_get_identity_hash_code (JNIEnv *env, void *v)
{
intptr_t rv = env->CallStaticIntMethod (monodroidRuntime.get_java_class_System (), monodroidRuntime.get_java_class_method_System_identityHashCode (), v);

jclass get_java_class_System () const
{
return java_System;
}

java_System = utils.get_class_from_runtime_field(env, runtimeClass, "java_lang_System", true);

Util::get_class_from_runtime_field (JNIEnv *env, jclass runtime, const char *name, bool make_gref)
{
static constexpr char java_lang_class_sig[] = "Ljava/lang/Class;";
jfieldID fieldID = env->GetStaticFieldID (runtime, name, java_lang_class_sig);
if (fieldID == nullptr)
return nullptr;
jobject field = env->GetStaticObjectField (runtime, fieldID);
if (field == nullptr)
return nullptr;
return reinterpret_cast<jclass> (make_gref ? osBridge.lref_to_gref (env, field) : field);
}

@brendanzagaeski
Copy link
Member Author

@grendello, does this look familiar by any luck?

@brendanzagaeski
Copy link
Member Author

@bolk, to check on a few details:

  • Are you still getting the behavior where the app exits during launch?
  • Have you noticed if it only happens with a specific emulator image?
  • Did you use the Tools > Device Manager in Visual Studio for Mac to set up the emulator originally?

@grendello
Copy link
Member

@brendanzagaeski nope, not familiar at all :( However, your analysis in Initial Notes seems to be correct. There are two possible reasons for java_System to be nullptr - one, we're running on Android older than API14 (unlikely, I suppose). Two, the following fails:

java_System = utils.get_class_from_runtime_field(env, runtimeClass, "java_lang_System", true);

There are several reasons why it would fail that come to mind. The code above tries to access this static field in our Java Runtime class. The reasons why it might be null are:

  • Runtime class doesn't exist for some reason (linked out? A dump of the .dex files in the apk would help here)
    Very unlikely as it's Runtime that contains the native initInternal method called here. Now, perhaps it's possible that the "java" part of the Runtime
    class is linked out by of the .dex files but the "native" call is still resolved and works? I don't know if that's even possible, /cc @jonpryor
  • java.lang.System.class returns null (very unlikely IMO)
  • JNI fails to locate the java_lang_System field in Runtime for some reason (clues in the logcat possibly?)

I can't offer much more than that, perhaps except for a diff to instrument the native code to track what happens around the code you indicated in Initial notes (I'll follow up with the diff in a separate comment)

grendello added a commit to grendello/xamarin-android that referenced this issue Apr 17, 2020
This PR adds some log messages which may help in tracing the cause of
issue xamarin#4570.
@grendello
Copy link
Member

@brendanzagaeski #4573 instead of the diff, perhaps we can fish out binaries from the PR build and use them to help track the issue.

@brendanzagaeski
Copy link
Member Author

@bolk, are you still seeing this behavior? If so, let us know, and I can send over the adjusted versions of Xamarin.Android that grendello prepared that will hopefully provide some extra logging information around the error.

Otherwise, I'll plan to close this item in 14 days. Thanks!

@brendanzagaeski brendanzagaeski added the need-info Issues that need more information from the author. label May 11, 2020
@bolk
Copy link

bolk commented May 13, 2020

Hi @brendanzagaeski sorry for my high latency, but I've been on other projects lately...
I'll give you feedback within this week.
Regards,
Alberto

@brendanzagaeski
Copy link
Member Author

No worries. Whenever you get a chance will be perfect. Thanks for the reply!

@bolk
Copy link

bolk commented May 25, 2020

Hello @brendanzagaeski, with the new release things seemes to have been fixed. Thank you

@brendanzagaeski
Copy link
Member Author

Perfect. Glad it's behaving as expected now. Thanks for checking!

@xamarin xamarin locked as resolved and limited conversation to collaborators Jun 4, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: App Runtime Issues in `libmonodroid.so`. need-info Issues that need more information from the author.
Projects
None yet
Development

No branches or pull requests

3 participants