Understanding a crash in Android Runtime (ART, OAT)

I have a crash happening in my Android games and I am a bit lost on how to fix this and wonder if I could find ideas and pointers.

The game uses cocos2d-x, so most of the code is C++ and it uses JNI.

It looks like the crash happens in ART (Android Runtime), and here is the callstack:

  #00  pc 00000000004d3c30  /apex/com.android.art/lib64/libart.so (art::OatHeader::IsDebuggable() const+64)
  #00  pc 00000000004d42dc  /apex/com.android.art/lib64/libart.so (art::OatFileBase::ShouldUnquickenVDex() const+56)
  #00  pc 00000000004d447c  /apex/com.android.art/lib64/libart.so (art::OatFileBase::LoadVdex(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)+80)
  #00  pc 00000000004d8508  /apex/com.android.art/lib64/libart.so (art::OatFile::Open(int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, bool, art::ArrayRef<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const>, art::MemMap*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)+468)
  #00  pc 00000000004ded18  /apex/com.android.art/lib64/libart.so (art::OatFileAssistant::OatFileInfo::GetFile()+696)
  #00  pc 00000000004ddfc0  /apex/com.android.art/lib64/libart.so (art::OatFileAssistant::OatFileInfo::Status()+76)
  #00  pc 00000000004de3e0  /apex/com.android.art/lib64/libart.so (art::OatFileAssistant::OatFileInfo::ReleaseFileForUse()+56)
  #00  pc 00000000004e387c  /apex/com.android.art/lib64/libart.so (art::OatFileManager::OpenDexFilesFromOat(char const*, _jobject*, _jobjectArray*, art::OatFile const**, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*)+292)
  #00  pc 0000000000497f20  /apex/com.android.art/lib64/libart.so (art::DexFile_openDexFileNative(_JNIEnv*, _jclass*, _jstring*, _jstring*, int, _jobject*, _jobjectArray*)+144)
  #00  pc 0000000000010a88  /apex/com.android.art/javalib/arm64/boot-core-libart.oat (art_jni_trampoline+264)
  #00  pc 000000000001f584  /apex/com.android.art/javalib/arm64/boot-core-libart.oat (dalvik.system.DexFile.openDexFile+244)
  #00  pc 00000000000213a0  /apex/com.android.art/javalib/arm64/boot-core-libart.oat (dalvik.system.DexPathList.makeDexElements+784)
  #00  pc 0000000000020b78  /apex/com.android.art/javalib/arm64/boot-core-libart.oat (dalvik.system.DexPathList.<init>+664)
  #00  pc 000000000001d934  /apex/com.android.art/javalib/arm64/boot-core-libart.oat (dalvik.system.BaseDexClassLoader.<init>+228)
  #00  pc 0000000000057bd0  /apex/com.android.art/javalib/arm64/boot-core-libart.oat (dalvik.system.DexClassLoader.<init>+80)
  #00  pc 0000000000133564  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548)
  #00  pc 00000000001a8a6c  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200)
  #00  pc 0000000000547e50  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeWithVarArgs<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, std::__va_list)+448)
  #00  pc 000000000054830c  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeWithVarArgs<_jmethodID*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+92)
  #00  pc 00000000003b5aa0  /apex/com.android.art/lib64/libart.so (art::JNI<false>::CallNonvirtualVoidMethodV(_JNIEnv*, _jobject*, _jclass*, _jmethodID*, std::__va_list)+644)
  #00  pc 00000000003993dc  /apex/com.android.art/lib64/libart.so (art::JNI<false>::NewObjectV(_JNIEnv*, _jclass*, _jmethodID*, std::__va_list)+748)
  #00  pc 00000000006df90c  /data/app/~~ynmNMMtpHquKFFPRfSbL0A==/com.frozax.tentsandtrees-mXRbcqMXPXclLGCQEmk8Fw==/lib/arm64/libMyGame.so (gpg::JavaClass::New(char const*, ...)+188)
  #00  pc 00000000006df714  /data/app/~~ynmNMMtpHquKFFPRfSbL0A==/com.frozax.tentsandtrees-mXRbcqMXPXclLGCQEmk8Fw==/lib/arm64/libMyGame.so (gpg::JavaClass::RegisterEmbeddedDexClassesInternal(gpg::JavaReference const&, bool*, char const*, char const*, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&, std::__ndk1::vector<gpg::JavaClass*, std::__ndk1::allocator<gpg::JavaClass*> > const&)+1420)
  #00  pc 00000000006df9dc  /data/app/~~ynmNMMtpHquKFFPRfSbL0A==/com.frozax.tentsandtrees-mXRbcqMXPXclLGCQEmk8Fw==/lib/arm64/libMyGame.so (gpg::JavaClass::RegisterEmbeddedDexClasses(gpg::JavaReference const&)+92)
  #00  pc 00000000006d8c90  /data/app/~~ynmNMMtpHquKFFPRfSbL0A==/com.frozax.tentsandtrees-mXRbcqMXPXclLGCQEmk8Fw==/lib/arm64/libMyGame.so (gpg::AndroidPlatformConfiguration::Valid() const+108)
  #00  pc 000000000070dc1c  /data/app/~~ynmNMMtpHquKFFPRfSbL0A==/com.frozax.tentsandtrees-mXRbcqMXPXclLGCQEmk8Fw==/lib/arm64/libMyGame.so (gpg::GameServices::Builder::Create(gpg::AndroidPlatformConfiguration const&)+76)
  #00  pc 00000000004c0ce4  /data/app/~~ynmNMMtpHquKFFPRfSbL0A==/com.frozax.tentsandtrees-mXRbcqMXPXclLGCQEmk8Fw==/lib/arm64/libMyGame.so (fgGPG::Install()+156)
  #00  pc 00000000004c33c0  /data/app/~~ynmNMMtpHquKFFPRfSbL0A==/com.frozax.tentsandtrees-mXRbcqMXPXclLGCQEmk8Fw==/lib/arm64/libMyGame.so (fgGame::Init()+1644)
  #00  pc 000000000048aa40  /data/app/~~ynmNMMtpHquKFFPRfSbL0A==/com.frozax.tentsandtrees-mXRbcqMXPXclLGCQEmk8Fw==/lib/arm64/libMyGame.so (SWG::Init()+1532)
  #00  pc 00000000004c4170  /data/app/~~ynmNMMtpHquKFFPRfSbL0A==/com.frozax.tentsandtrees-mXRbcqMXPXclLGCQEmk8Fw==/lib/arm64/libMyGame.so (fgGame::applicationDidFinishLaunching()+312)
  #00  pc 000000000057da18  /data/app/~~ynmNMMtpHquKFFPRfSbL0A==/com.frozax.tentsandtrees-mXRbcqMXPXclLGCQEmk8Fw==/lib/arm64/libMyGame.so (cocos2d::Application::run()+16)
  #00  pc 00000000005102e8  /data/app/~~ynmNMMtpHquKFFPRfSbL0A==/com.frozax.tentsandtrees-mXRbcqMXPXclLGCQEmk8Fw==/lib/arm64/libMyGame.so (Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit+356)
  #00  pc 0000000000038550  /data/app/~~ynmNMMtpHquKFFPRfSbL0A==/com.frozax.tentsandtrees-mXRbcqMXPXclLGCQEmk8Fw==/oat/arm64/base.odex (art_jni_trampoline+160)
  #00  pc 00000000001337e8  /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+568)
  #00  pc 00000000001a8a88  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+228)
  #00  pc 00000000003165dc  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+376)
  #00  pc 000000000030c6a0  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+912)
  #00  pc 0000000000670c4c  /apex/com.android.art/lib64/libart.so (MterpInvokeStatic+536)
  #00  pc 000000000012d994  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_static+20)
  #00  pc 00000000008703e4  /data/app/~~ynmNMMtpHquKFFPRfSbL0A==/com.frozax.tentsandtrees-mXRbcqMXPXclLGCQEmk8Fw==/oat/arm64/base.vdex (org.cocos2dx.lib.Cocos2dxRenderer.onSurfaceCreated+8)
  #00  pc 0000000000303e24  /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.7582775073154344913)+268)
  #00  pc 000000000065cac4  /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+760)
  #00  pc 000000000013cff8  /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88)
  #00  pc 0000000000622e18  /system/framework/arm64/boot-framework.oat (android.opengl.GLSurfaceView$GLThread.guardedRun+3144)
  #00  pc 0000000000623800  /system/framework/arm64/boot-framework.oat (android.opengl.GLSurfaceView$GLThread.run+224)
  #00  pc 0000000000133564  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548)
  #00  pc 00000000001a8a6c  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200)
  #00  pc 0000000000548990  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithJValues<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, jvalue const*)+460)
  #00  pc 00000000005970ec  /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*)+1288)
  #00  pc 00000000000af880  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+64)
  #00  pc 00000000000500d0  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64)

The last line of code that I have control of is in fgGPG::Install. In there, I call the initialization of the Google Play Games C++ SDK,using the function documented here: https://developers.google.com/games/services/cpp/api/class/gpg/game-services/builder#create.
According to the information I could get, when a user has this crash, it’s systematic and happens every time he launches the app on this device. I’ve seen it happen only on "Samsung S20+", "Samsung S20+ 5G", "Google Pixel 5" and "Google Pixel 4a", all on Android 11. I don’t know if it happens only to players who have an active Google Play Games account and it it happens to all players with a GPG account.

I’m no expert at all in ART, OAT and every other low level android features but if any of you has any lead that could help me fix this, that’d be awesome.

Source: Windows Questions C++

LEAVE A COMMENT