dotnet / dotnet/msbuild

BinaryLogger crashes child node with ObjectDisposedException in EnumerateMetadata

Open
#14,600 1 comment 0 reactions 0 assignees View on GitHub
triaged
Dominant language
C#
Stars
5.5k
Forks
1.5k
Avg merge
1d 8h
Merged PRs (30d)
141

Description

## Summary

MSBuild intermittently crashes with `MSB4166` (child node exited prematurely) due to a race condition in the BinaryLogger. The root cause is a `System.ObjectDisposedException` thrown when `BinaryLogger.Write` attempts to enumerate `ImmutableDictionary` metadata that has been concurrently disposed.

Tracked as a Known Build Error in dotnet/sdk: https://github.com/dotnet/sdk/issues/55076

## Stack trace

```
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'SortedInt32KeyNode1+Enumerator[ImmutableDictionary2+HashBucket[...]]'
at System.Collections.Immutable.SortedInt32KeyNode1.Enumerator.MoveNext()
at System.Collections.Immutable.ImmutableDictionary2.Enumerator.MoveNext()
at Microsoft.Build.Execution.ProjectItemInstance.TaskItem.EnumerateMetadata(...)
at Microsoft.Build.Logging.BuildEventArgsWriter.Write(ITaskItem item, ...)
at Microsoft.Build.Logging.BinaryLogger.Write(BuildEventArgs e)
```

## Reproduction

- Non-deterministic; occurs intermittently in CI builds that use `/bl` (binary logging).
- Observed in dotnet/sdk CI on various test legs. Retry always succeeds.
- Example failing build: https://dev.azure.com/dnceng-public/cbb18261-c48f-4abb-8651-8cdcb5474649/_build/results?buildId=1486641

## Root Cause

The lazy `EnumerateMetadata` enumeration over `ImmutableDictionary` in `ProjectItemInstance.TaskItem` races with disposal on another thread during binary log writing.

## Related

- Draft PR believed to fix this: https://github.com/dotnet/msbuild/pull/14115
- SDK known issue tracking: https://github.com/dotnet/sdk/issues/55076

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reading ProjectItemInstance.TaskItem.EnumerateMetadata and the BinaryLogger.Write/BuildEventArgsWriter.Write path shown in the stack trace, then reproduce with /bl in the referenced CI scenario if possible. Done means binary logging no longer crashes a child node with ObjectDisposedException during metadata enumeration; compare the behavior with draft PR #14115.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
build-system
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.