I’m having a weird issue when running my game on iOS:
Some minutes after running the game freezes and throws a crash. Usually, this happens when loading a scene, but sometimes it crashes during gameplay.
This is the stack trace I get in Crashlytics, it looks like the trace people are getting in this old thread :
It looks like the game is crashing when the garbage collector is working, that would explain why it crashes when loading scenes.
The game uses Addressables for all assets and scenes, I’m on Unity 2022.3.8f1, IL2CPP.
What I’ve tried so far without any success:
Disabling incremental GC
Temporarily removing any JSON serialization/deserialization
Commenting out all addressable “Release” calls
Building with minimal scenes (5 instead of all 60+)
I’ve tried everything I could and nothing changes anything, the game runs fine, loads scenes, and does everything as expected but out of nowhere it freezes, doesn’t crash to the home screen but logs the crash to Firebase. When the game freezes I can hear the audio chipping out.
Is there anything else I could try? Is this a known ting with 2022.3.x?
This is usually an indication of some memory corruption in a managed object allocated from the heap. The code in il2cpp::vm::LivenessState traverses the managed heap, building a graph of object references and trying to find assets that are no longer used and can be collected. It is not usually the cause of these problems, but it does often discover them.
Usually the causes fall into one of two camps:
Some code in your project is using unsafe C# code or native code that touches managed objects somehow, and causes this corruption.
Some code in Unity is corrupting a managed object
If you inspect your code and don’t find anything in camp (1), can you file a bug report with a project that causes this? WE can investigate it, and hopefully track down the code in Unity causing this, if that is the problem.
The issue started happening after upgrading from 2021 lts to 2022 lts and the introduction of the addressable a package. There are no “unsafe” keyword in the entire project, nor am I messing with managed code. I tried to reproduce with an empty project without any success, it might be a mix of too many addressables groups or the mix of packages the game uses. Sadly I don’t feel comfortable with sending my project.
When running from Xcode and looking at the logs every crash is happening seconds after an asset is loaded/unloaded inside an async function. I do lots of load/release calls since all spritesheets are in “pack separate” asset groups and loaded on demand.
Android is crashing in the same way, I just can’t confirm if the stack trace is the same since I’m not uploading debug symbols to firebase on development builds, but by the logcat I can see it’s happening at the same location as iOS.
Said that, I noticed the crashes stopped happening once I set stripping level to minimal (from high), low still crashes. Never had any issues with high stripping level before 2022+addressables. I’ll have to accept a higher bundle size until this can be fixed.
Interesting - I would not expect the stripping level to impact behavior like this. Can you submit this project with a bug report? It does sound like a problem on the Unity side. We definitely want to investigate and correct it.
Is there any news on this ? I’m facing pretty much the same problem using Unity 2022.3.0, and setting the stripped level to minimal doesn’t seems to fix anything.
Note that i’m not on iOS (but the platform is NDA restricted), and that I don’t have any unsafe code in the entire project.
I don’t believe we received a bug report on this, and we were not able to track it down otherwise. If you can submit a bug report, that would be really helpful.
I’ve just started getting this as well. Weirdly, when building the Xcode project on one machine the issue occurs as described above. However, zipping up that Xcode project, copying it another machine and then building/running there results in the issue disappearing. What’s that all about?!
I should mention that I’m seeing this on macOS, iOS and Android projects.
Update: taking the built macOS binary built on the problematic machine and running it on the other machine results in no issue. So perhaps this is a timing thing? The second machine is faster than the first, in my case…
Mine turned out to be loading a save game using a BinaryFormatter where the class layout had changed since the file was serialised. That explains why it worked on one machine but not the other. I’m not sure why Unity decided to die on its butt when attempting to do this (rather than throwing exceptions for me to handle), but that’s what was causing it. Specifically the call to BinaryFormatter.Deserialize().
I’m glad that you sorted this out! Unfortunately BinaryFormatter is not great overall, with cases like this not uncommon. If you have an option to use a different serialization format, I would recommend moving away from BinaryFormatter.
Thanks for getting back to me. Well I need my classes serialised into bytes for console support. Any advice on an alternative to BinaryFormatter? It seems that there are a few options, but all seem more complex and (to my mind) potentially more error prone that the “back to basics” BinaryFormatter. Would appreciate your insight if you have anything to suggest…
And inside that I used info.GetEnumerator() to loop over each SerializationInfo object until current.Name == “someProperty”. Then used current.ObjectType to see if it was the new Type or the old one. If it was the former I just assigned it directly to someProperty; if the latter then I wrote some code to construct the new Type from the old one.
Note: you also need to write GetObjectData(SerializationInfo info, StreamingContext context) if you implement ISerializable, which is kind of a pain…
Sorry, I don’t have a great solution here. I know from the many bug reports we have seen around BinaryFormatter that it can be tricky, but I don’t know enough about the solution space to suggest an alternative.
Hi, we’re seeing something very similar in 2021.3.9f1, which is affecting 99% iOS 17 users. I’ve double checked the code and don’t believe we’re using a BinaryFormatter anywhere.
0
UnityFramework
Class.cpp - Line 833
il2cpp::vm::Class::IsValuetype(Il2CppClass const*) + 833
1
UnityFramework
Liveness.cpp - Line 262
il2cpp::vm::LivenessState::TraverseObjects() + 262
2
UnityFramework
Liveness.cpp - Line 439
il2cpp::vm::LivenessState::TraverseArray(Il2CppArray*, il2cpp::vm::LivenessState*) + 439
3
UnityFramework
Liveness.cpp - Line 262
il2cpp::vm::LivenessState::TraverseObjects() + 262
4
UnityFramework
Liveness.cpp - Line 439
il2cpp::vm::LivenessState::TraverseArray(Il2CppArray*, il2cpp::vm::LivenessState*) + 439
5
UnityFramework
Liveness.cpp - Line 262
il2cpp::vm::LivenessState::TraverseObjects() + 262
6
UnityFramework
Liveness.cpp - Line 439
il2cpp::vm::LivenessState::TraverseArray(Il2CppArray*, il2cpp::vm::LivenessState*) + 439
7
UnityFramework
Liveness.cpp - Line 262
il2cpp::vm::LivenessState::TraverseObjects() + 262
8
UnityFramework
Liveness.cpp - Line 587
il2cpp::vm::Liveness::FromStatics(void*) + 587
9
UnityFramework
Time.h - Line 30
GarbageCollectSharedAssets(bool, bool) + 30
10
UnityFramework
UnloadUnusedAssetsOperation.cpp - Line 48
UnloadUnusedAssetsOperation::IntegrateMainThread() + 48
11
UnityFramework
PreloadManager.cpp - Line 402
PreloadManager::UpdatePreloadingSingleStep(PreloadManager::UpdatePreloadingFlags, int) + 402
12
UnityFramework
PreloadManager.cpp - Line 554
PreloadManager::UpdatePreloading() + 554
13
UnityFramework
PlayerLoop.cpp - Line 383
ExecutePlayerLoop(NativePlayerLoopSystem*) + 383
14
UnityFramework
PlayerLoop.cpp - Line 407
ExecutePlayerLoop(NativePlayerLoopSystem*) + 407
15
UnityFramework
PlayerLoop.cpp - Line 514
PlayerLoop() + 514
Update: The issue was an improper use of GameCenter, moving callbacks back and forth between threads and a custom MainThreadDispatcher we have that runs stuff on the main thread. Be careful with this kind of thing.