Skip to content

Fix native heap corruption in GitPackIndexMappedReaderTests#1360

Merged
AArnott merged 1 commit into
mainfrom
agents/fix-unstable-ubuntu-builds
Apr 15, 2026
Merged

Fix native heap corruption in GitPackIndexMappedReaderTests#1360
AArnott merged 1 commit into
mainfrom
agents/fix-unstable-ubuntu-builds

Conversation

@AArnott

@AArnott AArnott commented Apr 15, 2026

Copy link
Copy Markdown
Collaborator

Problem

The ubuntu-24.04 CI build has been failing non-deterministically with native heap corruption errors during test execution:

All four failures show the test host crashing with exit code 134 (SIGABRT) and zero actual test failures — the process dies during cleanup. A separate Windows build (#24473836691) also failed in the same test class (GetOffsetFromPartialTest) with a value-equality assertion failure on net472/x86.

Root Cause

Double-free of FileStream: GitPackIndexMappedReaderTests wrapped the FileStream in an explicit using block and passed it to GitPackIndexMappedReader, which takes ownership via MemoryMappedFile.CreateFromFile(..., leaveOpen: false). When the outer using block then tried to dispose the already-closed stream, the native file handle was freed twice — causing heap corruption on Linux.

Nullable struct equality: GetOffsetFromPartialTest compared GitObjectId? (boxed nullable) with GitObjectId (value type) using Assert.Equal. On .NET Framework x86, the boxing path could produce a false negative even when the underlying bytes matched.

Fix

  1. Remove the outer using on FileStream so GitPackIndexMappedReader is the sole owner
  2. Assert on objectId.Value.ToString() instead of comparing boxed nullable structs

The test was double-closing the FileStream: once via the explicit
'using' block on the FileStream variable, and again inside
GitPackIndexMappedReader.Dispose() which calls
MemoryMappedFile.Dispose() (created with leaveOpen: false).

On Linux/net10 this caused non-deterministic native heap corruption
(free(): invalid pointer, double free or corruption,
malloc_consolidate(): invalid chunk size) that crashed the test host
with exit code 134 — the pattern seen in 4 consecutive ubuntu-24.04
CI failures.

Additionally, the GetOffsetFromPartialTest assertions compared a
GitObjectId? (Nullable<GitObjectId>) against a GitObjectId value
type using Assert.Equal. On .NET Framework (net472/x86) the boxed
struct equality check could fail even when the underlying bytes
matched. Switch to comparing the string representation instead.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@AArnott AArnott enabled auto-merge April 15, 2026 21:24
@AArnott AArnott added this pull request to the merge queue Apr 15, 2026
Merged via the queue into main with commit 7fdd0b1 Apr 15, 2026
12 checks passed
@AArnott AArnott deleted the agents/fix-unstable-ubuntu-builds branch April 15, 2026 21:47
This was referenced Jun 19, 2026
This was referenced Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant