openfl / lime

A foundational Haxe framework for cross-platform development
https://lime.openfl.org/
MIT License
754 stars 368 forks source link

Android app exits on theme change #1532

Closed pozirk closed 2 years ago

pozirk commented 2 years ago

There is a problem, that most likely related to SDL. If I change Android theme from light to dark and vice versa, OpenFL app closes. It is not really crashing, as I couldn't find much in logs. Happens to any app, here is PiratePig video of the problem: https://youtube.com/shorts/hZSR0HdVa2Y

It wouldn't be a big deal, but Samsung AppStore suspended my game because of this. :confused:

Anyone has any idea on how to fix that? Thank you!

player-03 commented 2 years ago

Edit for new readers: Scroll down to reply 26 for a better picture of what's actually going on, or see #1545 for the resolution.


Obvious answer is to try updating SDL. Check out #1531 and see if that helps. (Remember to run both git submodule update and lime rebuild android -clean.)

pozirk commented 2 years ago

lime rebuild android -clean does nothing, no errors either. Does anything specific I need to do it on Windows? I have MSVC and Android NDK 21e installed and have no problem doing lime rebuild windows -clean.

I found error line in logs: Channel is unrecoverably broken and will be disposed!

player-03 commented 2 years ago

lime rebuild android -clean does nothing, no errors either.

That's very weird. No output at all?

Uh, ok. Check the ndll/Android folder to see if the files are there, and if so, check their timestamps to see if lime rebuild even touched them. Not sure what that would tell us, but I figure it'd be nice to have more info.

Next, move or delete those files to force it to rebuild.

Android NDK 21e installed

Also go through lime setup android and make sure you've got it selected. (Sheesh, there are a lot of little easy-to-forget steps...)

Channel is unrecoverably broken and will be disposed!

The logs for the Android app, right? Not lime rebuild? That's a fairly common message and doesn't mean much.

pozirk commented 2 years ago

Yep, no output at all for lime rebuild android -clean, ndll/Android is empty. lime setup android done of course, cause I'm building android projects, no problem.

I've also tried with the latest dev version of ndll/Android from github Artifacts, but still the same problem.

These logs from Android app, I guess I've found the whole trace:

#00 pc 00000000000b3e8c  /apex/com.android.runtime/lib64/bionic/libc.so (__cxa_finalize+148)
#01 pc 00000000000aee88  /apex/com.android.runtime/lib64/bionic/libc.so (exit+24)
#02 pc 0000000000f753dc  /data/app/~~KGQ4XeKrfFz1uUggaqoxDA==/org.openfl.samples.piratepig-QdRUZFT0P2K505H_XKzHpA==/lib/arm64/libApplicationMain.so
#03 pc 0000000000bc9b20  /data/app/~~KGQ4XeKrfFz1uUggaqoxDA==/org.openfl.samples.piratepig-QdRUZFT0P2K505H_XKzHpA==/lib/arm64/libApplicationMain.so
#04 pc 0000000000717e4c  /data/app/~~KGQ4XeKrfFz1uUggaqoxDA==/org.openfl.samples.piratepig-QdRUZFT0P2K505H_XKzHpA==/lib/arm64/libApplicationMain.so
#05 pc 0000000000e6ce30  /data/app/~~KGQ4XeKrfFz1uUggaqoxDA==/org.openfl.samples.piratepig-QdRUZFT0P2K505H_XKzHpA==/lib/arm64/libApplicationMain.so
#06 pc 0000000000e6b6bc  /data/app/~~KGQ4XeKrfFz1uUggaqoxDA==/org.openfl.samples.piratepig-QdRUZFT0P2K505H_XKzHpA==/lib/arm64/libApplicationMain.so
#07 pc 0000000000ed55cc  /data/app/~~KGQ4XeKrfFz1uUggaqoxDA==/org.openfl.samples.piratepig-QdRUZFT0P2K505H_XKzHpA==/lib/arm64/libApplicationMain.so
#08 pc 0000000000ed546c  /data/app/~~KGQ4XeKrfFz1uUggaqoxDA==/org.openfl.samples.piratepig-QdRUZFT0P2K505H_XKzHpA==/lib/arm64/libApplicationMain.so (hxcpp_main+56)
#09 pc 000000000049e254  /data/app/~~KGQ4XeKrfFz1uUggaqoxDA==/org.openfl.samples.piratepig-QdRUZFT0P2K505H_XKzHpA==/lib/arm64/liblime.so (Java_org_libsdl_app_SDLActivity_nativeRunMain+484)
#10 pc 000000000013ced4  /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+148)
#11 pc 00000000001337e8  /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+568)
#12 pc 00000000001a9804  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+228
#13 pc 000000000031c040  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+376)
#14 pc 0000000000312228  /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)
#15 pc 000000000068861c  /apex/com.android.art/lib64/libart.so (MterpInvokeStatic+548)
#16 pc 000000000012d994  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_static+20)
#17 pc 000000000000cc44  [anon:dalvik-classes.dex extracted in memory from /data/app/~~KGQ4XeKrfFz1uUggaqoxDA==/org.openfl.samples.piratepig-QdRUZFT0P2K505H_XKzHpA==/base.apk:0000006f1865c000] (org.libsdl.app.SDLMain.run+156)
#18 pc 00000000006873a4  /apex/com.android.art/lib64/libart.so (MterpInvokeInterface+1812)
#19 pc 000000000012da14  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_interface+20)
#20 pc 00000000000eb930  /apex/com.android.art/javalib/core-oj.jar (java.lang.Thread.run+8)
#21 pc 00000000003094d0  /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.15352004904310312929)+264)
#22 pc 00000000006740c0  /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+776)
#23 pc 000000000013cff8  /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88)
#24 pc 0000000000133564  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548)
#25 pc 00000000001a97e8  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200)
#26 pc 000000000055c384  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrI
nterfaceWithJValues<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, jvalue const*)+460)
#27 pc 00000000005ac204  /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*)+1308)
#28 pc 00000000000b0bd8  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+64)
#29 pc 00000000000505d0  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64)
...
InputDispatcher: channel 'e1814d8 org.openfl.samples.piratepig/org.openfl.samples.piratepig.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
pozirk commented 2 years ago

What about updating Lime's SDL files with the latest files from SDL? Github then will build me a nice ndll/Android on Pull request, hopefully without any errors and I can test it. Lime's SDL version is 2+ years already, should be updated sooner or later anyway, right? :smile:

player-03 commented 2 years ago

I did that in d21847e65c8c63811fc089cd9bc9e87e99751e6b. Not that Java files are included in the ndll...

pozirk commented 2 years ago

OK, I wasn't sure about that. But I've tried to take Lime from github + latest SDL java files, while app was building fine, it was crashing on start.

player-03 commented 2 years ago

I mean, if you didn't already have the correct Java files, then you may not have checked out my pull request, or perhaps didn't switch to the correct branch. If you run git log, does it match these commits?

pozirk commented 2 years ago

Nope, I didn't check your pull request, will try that. Thank you!

pozirk commented 2 years ago

So, I took Lime files from your Pull request #1531, and I took ndll/Android from this last Action, but now, after building the project, I'm getting an error on app launch: Screenshot_20220527-105313527_cr Also, ndll/Android/liblime.so was missing, don't know if it's a problem.

player-03 commented 2 years ago

I'm getting an error on app launch

Oh, you're right. Seems the arm64 target requires a few more files, but that's easy enough. New ndlls coming soon.

My one gripe is, the linker really should have been able to catch this. If it had, I could have fixed it much sooner.

Also, ndll/Android/liblime.so was missing, don't know if it's a problem.

That's the armv5 version, which I'm pretty sure no one uses anymore. Certainly hxcpp dropped support for it, so I removed it in 4d096d03e22c9377dfa8cef13d39af37071123e6.

pozirk commented 2 years ago

Unfortunately, this update didn't help with theme change, app still closes by itself. On top of that, I see just blank screen, so graphics stopped working. And if tap this blank screen long enough app crashes, see android log trace in attachment. adblogcat_crash.txt .

player-03 commented 2 years ago

You'll need to compile with -DHXCPP_DEBUG_LINK to get a readable stack trace. It needs to be a complete rebuild, so delete Export/android/obj before compiling, and be prepared to wait a while.

I'll have to try the PiratePig sample for myself.

pozirk commented 2 years ago

Added -DHXCPP_DEBUG_LINK to lime build didn't change much, I'm getting the same log output. My build command: lime build android -debug -DHXCPP_DEBUG_LINK. Do I need to rebuild ndll/Android with this flag? But I can't. :(

player-03 commented 2 years ago

Wow, you're right, it doesn't print the details. That's annoying, because it definitely used to. Oh well, that just means it's time to break out the big guns.

The link goes into depth, but a simple and reusable solution is to make yourself a .bat file.

adb logcat -d > logcat.txt
C:\path\to\ndk\r21e\ndk-stack -sym Export\android\bin\app\src\main\jniLibs\arm64-v8a" -i logcat.txt
del logcat.txt

Fill in the correct path to the NDK, save it somewhere in your PATH, and run it from your Lime project root.

pozirk commented 2 years ago

Finally had time to do it. Here is the file, there are 2 crash dumps in there, as they are a bit different: crashdump.txt

player-03 commented 2 years ago

Looks like both crashed when allocating memory. And this happened after a delay, so maybe a memory leak? I have no experience debugging those...

pozirk commented 2 years ago

Yes, it crashes after some delay, no need to tap anyway, just some 20 seconds into the blank screen of the game (it flickers black and white first). You think I have experience? :rofl: Any modification in rendering recently. Btw, are you getting the same crashes, cause maybe I've messed up something with Lime files.

player-03 commented 2 years ago

Finally got around to building PiratePig, and... it works for me. I tried it with the ndlls I compiled myself, and the ones from GitHub Actions. Both worked.

Here's the APK I made, if you want to try that. If not, we can try other things.

pozirk commented 2 years ago

Yep, your apk works for me, but still closing on theme change. I guess, I've messed up something with Lime files, will try from scratch next week.

player-03 commented 2 years ago

Seems I can reproduce the error. I'll take a closer look.

Update: it seems that two threads (hwuiTask0 and hwuiTask1) each call abort(), sending SIGABRT and closing the app. The two thread always have an identical stack, and the debugger always pauses right in the middle of both of them calling abort(), and it pauses once each (though IIRC it might highlight hwuiTask1 both times?). After those two pauses, the app closes.

I haven't found any information on what those threads are. From the stack trace, both seem to be trying to acquire a mutex (maybe both are after the same mutex?), but there's no other useful information there.

Not very much to go on...

pozirk commented 2 years ago

You are talking about "theme change" problem, right? Is it related to SDL? Then I can open an Issue with them.

player-03 commented 2 years ago

Yeah, same problem, same lack of information in the log. No idea if it's related to SDL, so it's too soon to submit an issue.

player-03 commented 2 years ago

Nope, not SDL. Not exclusively SDL, anyway.

I used their androidbuild.sh script to generate a sample project, and it survived the theme change just fine.

player-03 commented 2 years ago

Poking around some more, it seems unlikely that the mutexes are causing the issue. Rather, they've been disposed by something else that went wrong, and then they make it official when some other code attempts to use them. I say this because my tests involve closing the app at various points, and one of those was theoretically a clean exit, but the same two threads still ended up calling SIGABRT.

So perhaps something is interpreting the theme change as an instruction to exit, and the OS just sees an app exiting normally, which is why there's no error message.

Edit: that's exactly what's happening. For some reason, it's dispatching SDL_QUIT. Specifically, this block of code is being executed.

Edit 2: maybe it's fine that it's quitting? Apparently the OS relaunches the activity upon a theme change. But only once. Changing the theme after that keeps the activity running.

player-03 commented 2 years ago

I think I'm done with this. In case someone else wants to pick up the torch, here's what I've found. (Before I start: most of my testing was on Lime's develop branch, not my upcoming PR. Yes, I did a clean rebuild first.)

There's no documentation on any of this. Barely anyone talks about handleRelaunchActivity() or DestroyActivityItem, and never in the context of theme switching. Debuggers are not built to debug seemingly-legitimate shutdowns. And the only thing that even remotely seems to help actually gets the app stuck on a permanent blank screen.

pozirk commented 2 years ago

Thanks for all your help @player-03, I'll try to look into this myself.

player-03 commented 2 years ago

Good luck!

player-03 commented 2 years ago

Oh wait, they did document it after all. Not only is it explained, there's a very easy way to make it keep the activity. Give my pull request a shot and let me know.

We still don't know why Lime has to exit completely or get stuck with a blank screen, and it'd be nice to know, but I'm a lot less worried about that now that we have a workaround. Even if we knew the answer, we wouldn't do anything with that information. "Not restarting the activity in the middle of gameplay" is always going to be preferable to "successfully restarting the activity in the middle of gameplay."

pozirk commented 2 years ago

Unfortunately, I will only be able to check it somewhere at the end of June. I'm on vacation right now... 🍹

I was planning to spend countless hours on this when come back, but looks like you have found an easy solution. Thanks a lot!

pozirk commented 2 years ago

It works, adding uiMode fixes the problem, app doesn't exit anymore on theme change. Thank you @player-03!