Skip to content

Commit

Permalink
Fix NRE in target batching (#10185)
Browse files Browse the repository at this point in the history
Fixes #10180

### Context

#10102 made certain batching scenarios fail with a null-ref exception.

### Changes Made

Moved the call to `LogTargetBatchFinished` to make sure that the loop doesn't exit with null `targetLoggingContext`.

### Testing

New unit test with a repro project.
  • Loading branch information
ladipro authored May 29, 2024
1 parent 7ae92ce commit b963c24
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 10 deletions.
35 changes: 35 additions & 0 deletions src/Build.UnitTests/BackEnd/BatchingEngine_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,41 @@ public void UndefinedAndEmptyMetadataValues()
logger.AssertLogContains("[i1;i2 ]", "[i3 m1]");
}

/// <summary>
/// This is a regression test for https://github.com/dotnet/msbuild/issues/10180.
/// </summary>
[Fact]
public void HandlesEarlyExitFromTargetBatching()
{
string content = @"
<Project>
<ItemGroup>
<Example Include='Item1'>
<Color>Blue</Color>
</Example>
<Example Include='Item2'>
<Color>Red</Color>
</Example>
</ItemGroup>
<Target Name='Build'
Inputs='@(Example)'
Outputs='%(Color)\MyFile.txt'>
<NonExistentTask
Text = '@(Example)'
Output = '%(Color)\MyFile.txt'/>
</Target>
</Project>
";

Project project = new Project(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents(content))));
MockLogger logger = new MockLogger();
project.Build(logger);

// Build should fail with error MSB4036: The "NonExistentTask" task was not found.
logger.AssertLogContains("MSB4036");
}

private static Lookup CreateLookup(ItemDictionary<ProjectItemInstance> itemsByType, PropertyDictionary<ProjectPropertyInstance> properties)
{
return new Lookup(itemsByType, properties);
Expand Down
17 changes: 7 additions & 10 deletions src/Build/BackEnd/Components/RequestBuilder/TargetEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,13 @@ internal async Task ExecuteTarget(ITaskBuilder taskBuilder, BuildRequestEntry re
break;
}

if (i > 0)
{
// Don't log the last target finished event until we can process the target outputs as we want to attach them to the
// last target batch. The following statement logs the event for the bucket processed in the previous iteration.
targetLoggingContext.LogTargetBatchFinished(projectFullPath, targetSuccess, null);
}

targetLoggingContext = projectLoggingContext.LogTargetBatchStarted(projectFullPath, _target, parentTargetName, _buildReason);
bucket.Initialize(targetLoggingContext);
WorkUnitResult bucketResult = null;
Expand Down Expand Up @@ -565,16 +572,6 @@ internal async Task ExecuteTarget(ITaskBuilder taskBuilder, BuildRequestEntry re
entryForExecution?.LeaveScope();
aggregateResult = aggregateResult.AggregateResult(new WorkUnitResult(WorkUnitResultCode.Failed, WorkUnitActionCode.Stop, null));
}
finally
{
// Don't log the last target finished event until we can process the target outputs as we want to attach them to the
// last target batch.
if (targetLoggingContext != null && i < numberOfBuckets - 1)
{
targetLoggingContext.LogTargetBatchFinished(projectFullPath, targetSuccess, null);
targetLoggingContext = null;
}
}
}

// Produce the final results.
Expand Down

0 comments on commit b963c24

Please sign in to comment.