Search Issue Tracker
Third Party Issue
Third Party Issue in 6000.6.X
Votes
33
Found in
6000.0.67f1
6000.3.8f1
6000.4.0b8
6000.5.0a6
6000.6.0a1
Issue ID
UUM-134192
Regression
Yes
[Android][IL2CPP][ARMv7] Struct field value corrupts when invoking a generic delegate with a large struct by value
Reproduction steps:
1. Open the attached “IN-133974“ project
2. In the Android Player Settings, make sure that IL2CPP is selected as the Scripting backend and that only ARMv7 is selected as the Target Architecture (Project Settings > Player Settings > Other Settings)
3. Build and Run the Android Player
4. In the Player, click the “Test” button
5. Observe the result text field under the button
Actual result: The provided result is a random number, not equal to “300”
Expected result: The provided result is “300”
Reproducible with: 6000.0.67f1, 6000.2.0a2, 6000.3.8f1, 6000.4.0b8, 6000.5.0a6
Not reproducible with: 2022.3.71f1, 6000.2.0a1
Reproducible environments: macOS 26.2
Not reproducible environments: No other environments tested
Reproducible with these devices:
VLNQA00336 - HUAWEI Y6p (MED-LX9N), CPU: MediaTek MT6762R, GPU: PowerVR Rogue GE8320, OS: 10
VLNQA00583 - Xiaomi Redmi 9A (M2006C3LG), CPU: MediaTek Helio G25 (MT6762G), GPU: PowerVR Rogue GE8320, OS: 11
VLNQA00422 - Galaxy S21 Ultra 5G (SM-G998B), CPU: Exynos 2100, GPU: Mali-G78, OS: 11 (When only ARMv7 is enabled, when ARM64 is enabled, issue does not reproduce)
Comments (1)
-
unity_1401A9A0EA24A46A3B96
Feb 10, 2026 16:46
29 NDK fix this issue
Add comment
All about bugs
View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.
Latest issues
- An "InvalidOperationException" error is thrown when TryRemoveItem is used with rebuildTree set to false
- Build fails with IL2CPP error when building on Android platform in a specific project
- Resize to Fit option for Import Activity window's Columns does nothing
- Cell template field is reset and an "ArgumentException" is thrown when template was edited and UI Document is reopened
- Broken hyperlink formatting in HDRP 3D Sample Tutorials
Resolution Note:
Thank you for reporting a bug to Unity.
Our investigation indicates the issue originates from a third-party compiler issue in NDK 27. Because the problem lies outside our codebase, we're unable to address it directly at the moment, but it will be addressed in the future by an NDK 29 update.
When Writer<TestStruct>.write = DebugStruct is assigned in C#, IL2CPP stores it as an open static delegate. The Action_2_Invoke system routes through a generated OpenStatic trampoline. In NDK 27, the compiler incorrectly reordered a dependent store-then-load pair.
- Option 1: Pass by Reference: Change the delegate to use ref T. This avoids large-struct register splitting. delegate void RefAction<A, B>(A a, ref B b);
- Option 2: Use Reference Types Wrap the large internal State struct in a class. This shrinks the parent struct size to 8 bytes, keeping it in registers and avoiding the buggy stack-split path.
- Option 3: Avoid Generic Delegate Trampolines Call the method directly (DebugStruct(writer, item)) rather than through a generic Action<T> field.
Resolution Note (6000.6.X):
Thank you for reporting a bug to Unity.
Our investigation indicates the issue originates from a third-party compiler issue in NDK 27. Because the problem lies outside our codebase, we're unable to address it directly at the moment, but it will be addressed in the future by an NDK 29 update.
When Writer<TestStruct>.write = DebugStruct is assigned in C#, IL2CPP stores it as an open static delegate. The Action_2_Invoke system routes through a generated OpenStatic trampoline. In NDK 27, the compiler incorrectly reordered a dependent store-then-load pair.
- Option 1: Pass by Reference: Change the delegate to use ref T. This avoids large-struct register splitting. delegate void RefAction<A, B>(A a, ref B b);
- Option 2: Use Reference Types Wrap the large internal State struct in a class. This shrinks the parent struct size to 8 bytes, keeping it in registers and avoiding the buggy stack-split path.
- Option 3: Avoid Generic Delegate Trampolines Call the method directly (DebugStruct(writer, item)) rather than through a generic Action<T> field.