Background Assets: fix EXC_BAD_ACCESS in AssetPackManifest on iOS 26 (non-blittable baw_err) - #1
Closed
petarkarov wants to merge 1 commit into
Closed
petarkarov wants to merge 1 commit into
petarkarov wants to merge 1 commit into
Conversation
…(non-blittable baw_err) `Apple.BackgroundAssets.Error.baw_err` declared its `_static` field as a C# `bool`. A C# `bool` is not blittable, so IL2CPP generated a marshaled copy for every struct that embeds `baw_err`, including the union `baw_assetpackmanifest_res`. The generated unmarshal code copied the union's `success` member and then its `failure` member into the same bytes, so the second copy overwrote the first. On iOS 26 this destroyed the manifest's asset-pack array pointer, and the next call into the native wrapper crashed. Changing the field to `byte` makes `baw_err` blittable, so IL2CPP passes the union through untouched and the crash disappears. The field is never read on the C# side, so there is no behavior change beyond the fix.
Owner
Author
|
Opened against the wrong base by mistake — correct PR is apple#114. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Apple.BackgroundAssets.Error.baw_errdeclares its_staticfield as a C#bool. A C#boolis not blittable, so IL2CPP generates a marshaled copy for every struct that embedsbaw_err, including the unionbaw_assetpackmanifest_res. The generated unmarshal code copies the union'ssuccessmember and then itsfailuremember into the same bytes, so the second copy overwrites the first. On iOS 26 this destroys the manifest's asset-pack array pointer, and the next call into the native wrapper crashes.Changing the field to
bytemakesbaw_errblittable. IL2CPP then passes the union through untouched and the crash disappears. The field is never read on the C# side, so there is no behavior change beyond the fix.Symptom
On any iOS 26 device (tested on 26.5), the first call to
AssetPackManifest.GetAssetPack()orGetAllAssetPacks()afterAssetPackManager.GetManifestAsync()crashes:The faulting instruction is
ldr x1, [x21]wherex21iscManifest.compat.assetpackv, and its value is1.iOS 27 is not affected: there the manifest is stored as a single opaque pointer in the first 8 bytes of the union, which the overwrite happens to leave intact.
Root cause
IL2CPP output for the reverse P/Invoke wrapper of
ManifestCallback(Unity 6000.4.0f1):successandfailureoverlap at offset 0. After the second assignment, bytes 8..15 contain0x0000000000000001(theboolconverted from the marshaledint32), which is wherebaw_assetpackmanifest_compat.assetpackvlives on iOS 26.A secondary mismatch is fixed by the same change: C
boolis 1 byte, but C#boolis marshaled as a 4-byteBOOLby default, so_staticwas also being read from padding.Fix
[StructLayout(LayoutKind.Sequential)] internal struct baw_err { internal IntPtr description; - bool _static; + byte _static; }With this change the generated wrapper takes
baw_assetpackmanifest_res_t...directly instead of a_marshaled_pinvokevariant, and no copy is performed.Verification
ReversePInvokeWrapper_AssetPackManager_ManifestCallbacknow takes the raw struct.Notes
The same pattern applies to every other union that embeds
baw_err(baw_assetpack_status_res,baw_assetpackmanager_assetpack_update_res, and the plainbaw_errcallbacks). They didn't crash only because their overlapping bytes happened to carry the same values, so this change makes them correct as well.