dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.27k stars 4.73k forks source link

StackOverflow in mscordaccore.dll #105950

Closed adamsitnik closed 3 months ago

adamsitnik commented 3 months ago

BenchmarkDotNet is using ClrMD to obtain disassembly: the host process starts the benchmarking process and once the benchmarking is finished, it attaches to the benchmark process by using the debugger APIs.

After updating from Preview 6 to 7, I get StackOverflow when both host and benchmark process are net9.0 (9.0.100-preview.7.24402.8 to be exact):

Stack overflow.
   at Microsoft.Diagnostics.Runtime.DacInterface.SOSDac.GetCommonMethodTables(Microsoft.Diagnostics.Runtime.DacInterface.CommonMethodTables ByRef)
   at Microsoft.Diagnostics.Runtime.Builders.RuntimeBuilder.Microsoft.Diagnostics.Runtime.Implementation.IRuntimeHelpers.GetBaseClassLibrary(Microsoft.Diagnostics.Runtime.ClrRuntime)
   at Microsoft.Diagnostics.Runtime.Implementation.ClrmdRuntime.Initialize()
   at Microsoft.Diagnostics.Runtime.Builders.RuntimeBuilder..ctor(Microsoft.Diagnostics.Runtime.ClrInfo, Microsoft.Diagnostics.Runtime.DacLibrary, Microsoft.Diagnostics.Runtime.DacInterface.SOSDac)
   at Microsoft.Diagnostics.Runtime.ClrInfo.ConstructRuntime(System.String)
   at Microsoft.Diagnostics.Runtime.ClrInfo.CreateRuntime(System.String, Boolean)
   at Microsoft.Diagnostics.Runtime.ClrInfo.CreateRuntime()
   at BenchmarkDotNet.Disassemblers.ClrMdV2Disassembler.AttachAndDisassemble(BenchmarkDotNet.Disassemblers.Settings)
   at BenchmarkDotNet.Disassemblers.SameArchitectureDisassembler.Disassemble(BenchmarkDotNet.Diagnosers.DiagnoserActionParameters)
   at BenchmarkDotNet.Diagnosers.DisassemblyDiagnoser.Handle(BenchmarkDotNet.Engines.HostSignal, BenchmarkDotNet.Diagnosers.DiagnoserActionParameters)
   at BenchmarkDotNet.Diagnosers.CompositeDiagnoser.Handle(BenchmarkDotNet.Engines.HostSignal, BenchmarkDotNet.Diagnosers.DiagnoserActionParameters)
   at BenchmarkDotNet.Loggers.Broker.ProcessDataBlocking()
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(System.Threading.Thread, System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef, System.Threading.Thread)
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading.PortableThreadPool+WorkerThread.WorkerThreadStart()

When the host app is net8.0 and benchmark is net9.0 the app just crashes, here is what I've found in Event Viewer:

Faulting application name: BdnAllocsRepro.exe, version: 1.0.0.0, time stamp: 0x666b0000
Faulting module name: mscordaccore.dll, version: 9.0.24.40108, time stamp: 0x66abf7a1
Exception code: 0xc0000005
Fault offset: 0x000000000004343b
Faulting process id: 0x0x4910
Faulting application start time: 0x0x1DAE74683CFDC5B
Faulting application path: C:\Users\adsitnik\source\repos\BdnAllocsRepro\bin\Release\net8.0\BdnAllocsRepro.exe
Faulting module path: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\9.0.0-preview.7.24401.8\mscordaccore.dll
Report Id: 7865d16f-311e-4769-ad63-ba673c8dcf89
Faulting package full name: 
Faulting package-relative application ID: 

Repro:

```xml Exe net8.0;net9.0 enable enable ``` ```cs using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Running; namespace BdnAllocsRepro { internal class Program { static void Main(string[] args) { BenchmarkSwitcher.FromAssembly(typeof(Tests).Assembly).Run(args); } } [MemoryDiagnoser] [HideColumns("Job", "Error", "StdDev", "Median", "RatioSD")] public partial class Tests { private KeyValuePair[] _data = [ new("key1", "value1"), new("key2", "value2"), new("key3", "value3"), new("key4", "value4") ]; [Benchmark] public FormUrlEncodedContent Create() => new FormUrlEncodedContent(_data); } } ``` Both processes being net9.0: ```cmd dotnet run -c Release -f net9.0 --filter * --disasm --disasmFilter *FormUrlEncodedContent* ``` Host being 8.0 and benchmark being 9.0: ```cmd dotnet run -c Release -f net8.0 --filter * --runtimes net9.0 --disasm --disasmFilter *FormUrlEncodedContent* ```

cc @janvorli @jkotas

dotnet-policy-service[bot] commented 3 months ago

Tagging subscribers to this area: @tommcdon See info in area-owners.md if you want to be subscribed.

jkotas commented 3 months ago

@elinor-fung @lambdageek Regression from the cDac work?

lambdageek commented 3 months ago

Did https://github.com/dotnet/runtime/pull/105366 make it into preview 7? Update no it did not

elinor-fung commented 3 months ago

Backport PR: https://github.com/dotnet/runtime/pull/105962

adamsitnik commented 3 months ago

Should we also add some simple tests that use ClrMD to ensure such bugs don't come back?

tommcdon commented 3 months ago

Fixed in https://github.com/dotnet/runtime/pull/105962 (preview 7) as well as https://github.com/dotnet/runtime/pull/105366 (main)