-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Closed
Labels
area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMICLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Milestone
Description
Description
With .NET 10 I'm seeing an unexpected IndexOutOfRangeException. It doesn't repro in .NET 9 or with JIT optimizations disabled, so that hints to it being a JIT codegen issue.
Reproduction Steps
Unfortunately this isn't a "minimal" repro, but it doesn't require much to get set up.
TrackerExecutor.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.BuildXL.Processes" Version="0.1.0-20241105.3" />
</ItemGroup>
</Project>Program.cs
// Copyright (C) Microsoft Corporation. All Rights Reserved.
using System;
using System.IO;
using System.Threading.Tasks;
using BuildXL.Processes;
using BuildXL.Utilities.Core;
namespace DBS.TrackerExecutor;
public static class Program
{
public static async Task Main()
{
////System.Diagnostics.Debugger.Launch();
string tempDir = Path.Combine(Directory.GetCurrentDirectory(), ".tmp");
if (Directory.Exists(tempDir))
{
Directory.Delete(tempDir, recursive: true);
}
await Parallel.ForAsync(0, 100, async (i, ct) =>
{
string workingDirectory = Path.Combine(tempDir, Guid.NewGuid().ToString());
await RunInternalAsync(workingDirectory);
});
}
private static async Task RunInternalAsync(string workingDirectory)
{
Directory.CreateDirectory(workingDirectory);
var eventListener = new DetoursEventListener();
eventListener.SetMessageHandlingFlags(MessageHandlingFlags.DebugMessageNotify | MessageHandlingFlags.FileAccessNotify | MessageHandlingFlags.ProcessDataNotify | MessageHandlingFlags.ProcessDetoursStatusNotify);
var info = new SandboxedProcessInfo(
fileStorage: null,
fileName: @"C:\Program Files\dotnet\dotnet.exe",
disableConHostSharing: false,
detoursEventListener: eventListener,
createJobObjectForCurrentProcess: true)
{
PipSemiStableHash = 0,
PipDescription = "Process Invocation",
Arguments = @"new console",
WorkingDirectory = workingDirectory,
EnvironmentVariables = BuildParameters.GetFactory().PopulateFromEnvironment(),
// Don't buffer any output.
MaxLengthInMemory = 0,
};
info.FileAccessManifest.FailUnexpectedFileAccesses = false;
info.FileAccessManifest.MonitorChildProcesses = true;
info.FileAccessManifest.IgnoreReparsePoints = true;
info.FileAccessManifest.UseExtraThreadToDrainNtClose = false;
info.FileAccessManifest.UseLargeNtClosePreallocatedList = true;
info.FileAccessManifest.LogProcessData = true;
info.FileAccessManifest.ReportProcessArgs = true;
info.FileAccessManifest.NormalizeReadTimestamps = false;
SandboxedProcessResult sandboxProcessResult;
using SandboxedProcess process = await SandboxedProcess.StartAsync(info);
sandboxProcessResult = await process.GetResultAsync();
}
private sealed class DetoursEventListener : IDetoursEventListener
{
public override void HandleFileAccess(FileAccessData fileAccessData)
{
}
public override void HandleDebugMessage(DebugData debugData)
{
}
public override void HandleProcessData(ProcessData processData)
{
}
public override void HandleProcessDetouringStatus(ProcessDetouringStatusData data)
{
}
}
}NuGet.config:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<configuration>
<packageSources>
<clear />
<add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />
</packageSources>
</configuration>Run dotnet run and you should see something like (among ignorable irrelevant console spew):
OnUnhandledException called recursively
at System.Environment.FailFast(System.Runtime.CompilerServices.StackCrawlMarkHandle, System.String, System.Runtime.CompilerServices.ObjectHandleOnStack, System.String)
at System.Environment.FailFast(System.Threading.StackCrawlMark ByRef, System.String, System.Exception, System.String)
at System.Environment.FailFast(System.String)
at System.AppContext.OnUnhandledException(System.Object)
at System.Runtime.EH.DispatchEx(System.Runtime.StackFrameIterator ByRef, ExInfo ByRef)
at System.Runtime.EH.RhThrowEx(System.Object, ExInfo ByRef)
at Internal.Runtime.CompilerHelpers.ThrowHelpers.ThrowIndexOutOfRangeException()
at BuildXL.Native.Streams.OverlappedPool.ReserveOverlappedWithTarget(BuildXL.Native.Streams.IIOCompletionTarget)
at BuildXL.Processes.Internal.AsyncPipeReader.BuildXL.Native.Streams.IIOCompletionTarget.OnCompletion(BuildXL.Native.Streams.FileAsyncIOResult)
at System.Threading.QueueUserWorkItemCallbackDefaultContext.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool+WorkerThread.WorkerThreadStart()
at System.Threading.Thread.StartCallback()
Expected behavior
Not a crash
Actual behavior
Unhandled exception.
Regression?
Yes, this worked in .NET 9
Known Workarounds
No response
Configuration
No response
Other information
From looking at the disassembly, I believe it's a bounds check that's causing the exception, specifically this one below (despite what the debugger says):

Metadata
Metadata
Assignees
Labels
area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMICLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI