Skip to content

Fix SIGBUS crash on ARMv7: use Unsafe.ReadUnaligned in Frozen.Hashing#127653

Merged
jkotas merged 3 commits intomainfrom
copilot/fix-sigbus-crash-armv7
May 1, 2026
Merged

Fix SIGBUS crash on ARMv7: use Unsafe.ReadUnaligned in Frozen.Hashing#127653
jkotas merged 3 commits intomainfrom
copilot/fix-sigbus-crash-armv7

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 1, 2026

System.Collections.Frozen.Hashing was casting char* to uint* and dereferencing directly, causing unaligned 32-bit reads. On ARMv7 (e.g., Android Unity IL2CPP), the OS does not fixup misaligned accesses, resulting in SIGBUS crashes when calling ToFrozenSet<string>(StringComparer.Ordinal) on strings with length ≥ 4.

Changes

  • Hashing.GetHashCodeOrdinal — replaced ((uint*)src)[n] and uint* ptrUInt32 loop with Unsafe.ReadUnaligned<uint>(ptr) / Unsafe.ReadUnaligned<uint>(ptr + 2)
  • Hashing.GetHashCodeOrdinalIgnoreCaseAscii — same fix applied; same unaligned access pattern existed independently
  • Added using System.Runtime.CompilerServices for Unsafe

Before (both methods, case 4 and default):

// Crashes on ARMv7 when src is not 4-byte aligned
hash1 = ... ^ ((uint*)src)[0];
hash2 = ... ^ ((uint*)src)[1];

uint* ptrUInt32 = (uint*)src;
while (length >= 4)
{
    hash1 = ... ^ ptrUInt32[0];
    hash2 = ... ^ ptrUInt32[1];
    ptrUInt32 += 2;
    ...
}

After:

hash1 = ... ^ Unsafe.ReadUnaligned<uint>(src);
hash2 = ... ^ Unsafe.ReadUnaligned<uint>(src + 2);

char* ptr = src;
while (length >= 4)
{
    hash1 = ... ^ Unsafe.ReadUnaligned<uint>(ptr);
    hash2 = ... ^ Unsafe.ReadUnaligned<uint>(ptr + 2);
    ptr += 4;
    ...
}

Copilot AI requested review from Copilot and removed request for Copilot May 1, 2026 16:24
@github-actions github-actions Bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label May 1, 2026
Copilot AI requested review from Copilot and removed request for Copilot May 1, 2026 16:49
Copilot AI changed the title [WIP] Fix SIGBUS crash on ARMv7 in GetHashCodeOrdinal Fix SIGBUS crash on ARMv7: use Unsafe.ReadUnaligned in Frozen.Hashing May 1, 2026
Copilot finished work on behalf of jkotas May 1, 2026 16:50
Copilot AI requested a review from jkotas May 1, 2026 16:50
@github-actions github-actions Bot added area-System.Collections and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels May 1, 2026
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-system-collections
See info in area-owners.md if you want to be subscribed.

@jkotas jkotas marked this pull request as ready for review May 1, 2026 17:02
Copilot AI review requested due to automatic review settings May 1, 2026 17:02
@jkotas jkotas requested a review from EgorBo May 1, 2026 17:03
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a SIGBUS crash on ARMv7 caused by unaligned 32-bit reads in System.Collections.Frozen string hashing, by switching from char*uint* dereferences to explicit unaligned reads via Unsafe.ReadUnaligned<uint>.

Changes:

  • Replaced unaligned uint* dereferences in Hashing.GetHashCodeOrdinal with Unsafe.ReadUnaligned<uint> to safely read 32-bit chunks from potentially unaligned char*.
  • Applied the same unaligned-read fix to Hashing.GetHashCodeOrdinalIgnoreCaseAscii.
  • Added using System.Runtime.CompilerServices; for Unsafe.

@jkotas jkotas enabled auto-merge (squash) May 1, 2026 17:28
@jkotas jkotas merged commit 13b9f37 into main May 1, 2026
91 checks passed
@jkotas jkotas deleted the copilot/fix-sigbus-crash-armv7 branch May 1, 2026 19:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SIGBUS crash on ARMv7 in System.Collections.Frozen.Hashing.GetHashCodeOrdinal

4 participants