Description
A few months ago, I updated my iOS app from Xamarin.iOS directly to .NET 9.0.4. After the release on the App Store, it started getting crashes after random user actions or sometimes even bindings being triggered.
After lots of attempts, I was able to catch it and, unfortunately, Humanizer was the source. On removing it from the app, the crashes are gone in the new version.
All crashes look like the GC stumbling over some unreleased memory in drain_gray_stack…
:
KERN_INVALID_ADDRESS at 0x200000100.
Thread 1 Crashed:
0 iOS 0x206122260 [inlined] major_copy_or_mark_object_concurrent_no_evacuation (sgen-marksweep-drain-gray-stack.h:137)
1 iOS 0x206122260 [inlined] major_scan_object_concurrent_no_evacuation (sgen-scan-object.h:66)
2 iOS 0x206122260 [inlined] drain_gray_stack_concurrent_no_evacuation (sgen-marksweep-drain-gray-stack.h:347)
3 iOS 0x206122260 drain_gray_stack_concurrent (sgen-marksweep.c:1306)
4 iOS 0x206141294 marker_idle_func (sgen-workers.c:363)
5 iOS 0x2061401cc thread_func (sgen-thread-pool.c:219)
Other common patterns:
- Almost all crashes have happened with 50-120 MB free memory on the device;
- Crashes happen only in Release mode;
- Enabling/disabling
EnableSGenConc
seems to have no effect; - Enabling
UseInterpreter
stops them, but of course slows the app down.
I added a debug pane for the Release mode, but even opening heavy apps or games doesn't consistently decrease the free memory to fewer than 500 MB, so the crashes have been really hard to reproduce.
The trick turned out to be causing GC to run manually:
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
…while having the app running in Release mode on the iOS simulator.
So, the steps to reproduce are:
- Download the sample project
- Run it on Mac, in Release mode, any modern iOS 16.4-18.4
- Tap "Call Humanizer", then "Run Garbage Collector"
gc.mp4
Would be great if you can look into this. I hope to get Humanizer back into my app 🙏