Strange crashes in the Android file opening code (ExceptionOccurred)

So I have a game-port I did for a developer to Android and I am receiving a large number of crash reports for some users where game crashes on startup loading assets. (seems to be only on Android 12 / newer devices like the pixel 6)

The code is simply doing SDL_RWFromFile to load a datafile from the pak. Where it is crashing is in the Internal_Android_Create_AssetManager when trying to connect to the activity class.

So, this looks like the SDL code is lacking some ExceptionOccurred checks throughout the code (of which I see only 2!) and we should probably be checking in more locations.

Also, anyone know how to make android report better information on what this exception actually is? As google play console shows nothing but this backtrace. Thus I have no idea what exception is actually being created.

(Backtrace)

#00 pc 000000000004f85c /apex/com.android.runtime/lib64/bionic/libc.so (abort+168)
#00 pc 000000000062689c /apex/com.android.art/lib64/libart.so (art::Runtime::Abort(char const*)+704)
#00 pc 000000000001595c /apex/com.android.art/lib64/libbase.so (android::base::SetAborter(std::__1::function<void (char const*)>&&)::$_3::__invoke(char const*)+76)
#00 pc 0000000000014f8c /apex/com.android.art/lib64/libbase.so (android::base::LogMessage::~LogMessage()+364)
#00 pc 00000000004501fc /apex/com.android.art/lib64/libart.so (art::JavaVMExt::JniAbort(char const*, char const*)+2516)
#00 pc 00000000004675ec /apex/com.android.art/lib64/libart.so (art::JNI::GetObjectClass(_JNIEnv*, _jobject*)+1416)
#00 pc 000000000007927c /data/app/~~g1_3ESY98GHn-rcYTh6Jyw==/-UFAKdjiNcLanX0sBdrKfUQ==/split_config.arm64_v8a.apk!libSDL2.so
#00 pc 00000000000791c8 /data/app/~~g1_3ESY98GHn-rcYTh6Jyw==/-UFAKdjiNcLanX0sBdrKfUQ==/split_config.arm64_v8a.apk!libSDL2.so (Android_JNI_FileOpen+40)
#00 pc 0000000000091424 /data/app/~~g1_3ESY98GHn-rcYTh6Jyw==/-UFAKdjiNcLanX0sBdrKfUQ==/split_config.arm64_v8a.apk!libSDL2.so (SDL_RWFromFile_REAL+328)

It sounds strange,
but from the stack-trace, as you said, it crashes in Internal_Android_Create_AssetManager()

which is strange …

“env” should be valid otherwise it would have crashed before.
maybe context is bad. (It would interesting to test with 0 or -1).

how many crash reports (total and users) do you have ?
which targetSdkVersion do you use ?

compile & target is 30, min sdk 19. (sdl libs were also build as min 19, target 30).
This is only happening on a handful of users (right now 14) but ALL are on google pixel 6 / 6 pro. And on another game (13 users) for the same developer we have a very similar crash on startup too (but this time in calling (Android_JNI_GetLocale+76) in the same GetObjectClass method).

The first game has a current user base of ~2400… the other game ~15K.

The issue is these affected users it crashes 100% of the time for them.

I actually updated all 3 games for the developers they have out and 2 of the 3 are exhibiting this behavior (all compiles the SAME way, SAME SDK/NDK and literal same libSDL2 build).

They are all using the new “bundle” packaging on google play, so the main game assets are in a resource pak (configured to be made available at install time).

FYI (if you want to test them) the game are all of Tomorrow Coprorations games (Human resource machine, little inferno and 7 billion humans).

The backtrace in my first post is from 7bh… the other crash was in Little inferno. (which actually has a minSDK of 21 not 19).

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 0 >>> com.littleinferno.google <<<

backtrace:
  #00  pc 000000000004f85c  /apex/com.android.runtime/lib64/bionic/libc.so (abort+168)
  #00  pc 000000000062689c  /apex/com.android.art/lib64/libart.so (art::Runtime::Abort(char const*)+704)
  #00  pc 000000000001595c  /apex/com.android.art/lib64/libbase.so (android::base::SetAborter(std::__1::function<void (char const*)>&&)::$_3::__invoke(char const*)+76)
  #00  pc 0000000000014f8c  /apex/com.android.art/lib64/libbase.so (android::base::LogMessage::~LogMessage()+364)
  #00  pc 00000000004501fc  /apex/com.android.art/lib64/libart.so (art::JavaVMExt::JniAbort(char const*, char const*)+2516)
  #00  pc 00000000004675ec  /apex/com.android.art/lib64/libart.so (art::JNI<false>::GetObjectClass(_JNIEnv*, _jobject*)+1416)
  #00  pc 000000000007927c  /data/app/~~KYcB1zIKpybpwfBK0-EmPg==/com.littleinferno.google-tqTkdcNNcVB0BB2cKwMILQ==/split_config.arm64_v8a.apk!libSDL2.so
  #00  pc 000000000007ad44  /data/app/~~KYcB1zIKpybpwfBK0-EmPg==/com.littleinferno.google-tqTkdcNNcVB0BB2cKwMILQ==/split_config.arm64_v8a.apk!libSDL2.so (Android_JNI_GetLocale+76)
  #00  pc 00000000000a61b0  /data/app/~~KYcB1zIKpybpwfBK0-EmPg==/com.littleinferno.google-tqTkdcNNcVB0BB2cKwMILQ==/split_config.arm64_v8a.apk!libSDL2.so (SDL_GetPreferredLocales_REAL+308)

The crash appears in GetObjectClass, it call “JniAbort”.
GetLocale also needs the asset manager. Could it be possible that you’ve threads, and a concurrency issue inbetween SDL_GetPreferredLocales and the SDL_RWops loading ?
Or maybe some corrupted memory … Valgrind would help if possible ?

The crash seems very frequent ! (1% on the first game).
Personally, don’t see those crashes at all on a larger base of users.
( I use the aab bundle. but no separate assets package and still target Sdk 29)

This code is in a background thread, yes. but I have never seen this crash before in all of our testing And only seems to be happening on android 12 on SOME devices (I have no physical 12 devices to test on). (does not occur in x86_64 emulator… need to test arm64 emulator)

Also, wouldn’t the error be happening in the PREVIOUS call? From my understanding of the Exception handling in JNI, you have to make an additional call to check Exceptions, thus wouldn’t CallStaticObjectMethod be the one actually causing the issue? (e.g. the context is very wrong).

Perhaps I should try just adding a catch around that and see what it logs and send a build off to the user.

Without knowing much about the topic, it really sounds like there’s been some sort of problem with the assets not getting installed properly on the affected devices. Maybe there’s some sort of bug or “feature” that allows the game to run even when those assets are unavailable, resulting in this funky behavior.

Maybe a timing issue because pixel 6 is faster. or an issue with android 12.

you can:

  • try to test on a real device to force a concurrency, you call in 2 threads in parallel something like
    while(1) {
    Internal_Android_Create_AssetManager();
    Internal_Android_Destroy_AssetManager();
    … + some SDL_Log or SDL_Delay
    }
    and see if it crashes the same way …
    but you need to modify SDL a little bit for that, it shouldn’t be complicated.

  • you can try to fake the previous call with a context NULL or -1. or throwing an exeception in the java side… it should fail, but it shouldn’t get GetObjectClass crashed. but it’s worth trying

@meklu maybe an installation issue, but it hasn’t reached the assets loading intructions.

@Edward_Rudd
if you can send a build to the user, it can be easier to find what’s the issue