-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Description
In .NET 9 RC 1 I observe problems with reporting event counters from the System.Runtime
provider.
Reproduction Steps
I have following test application:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
public class ControlledExitProgram
{
private class InterprocessEvent
{
private readonly string myId;
public InterprocessEvent(string id)
{
myId = id;
}
public void Set()
{
Console.WriteLine(myId);
}
public void SetWaited()
{
WaitOne();
Console.WriteLine(myId);
}
public void WaitOne()
{
var line = Console.ReadLine();
if (line != myId)
throw new ApplicationException(string.Format("Unexpected input: {0}. Event {1} is expected.", line, myId));
}
}
private static string GetReadySignalId(int pid) => $"{nameof(ControlledExitProgram)}.Ready.{pid}";
private static string GetExitSignalId(int pid) => $"{nameof(ControlledExitProgram)}.Exit.{pid}";
private static string GetResponseSignalId(int pid) => $"{nameof(ControlledExitProgram)}.Response.{pid}";
private static InterprocessEvent CreateEvent(string id) => new InterprocessEvent(id);
public static void Main(string[] args)
{
var readyEvent = CreateEvent(GetReadySignalId(Process.GetCurrentProcess().Id));
readyEvent.SetWaited();
var typeName = args[0];
var type = Type.GetType(typeName);
var constructor = type.GetConstructor(new Type[]{});
var parameters = new object[] { };
constructor.Invoke(parameters);
var waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
Task.Factory.StartNew(() =>
{
var exitEvent = CreateEvent(GetExitSignalId(Process.GetCurrentProcess().Id));
exitEvent.WaitOne();
waitHandle.Set();
});
while (true)
{
try
{
throw new Exception();
}
catch {}
var list = new List<object>();
var iterationsCount = 1000000;
while (iterationsCount-- > 0)
list.Add(constructor.Invoke(parameters));
Console.WriteLine(list.Aggregate(0, (hash, o) => hash ^ o.GetHashCode()));
GC.Collect();
if (waitHandle.WaitOne(TimeSpan.FromSeconds(1)))
{
var responseEvent = CreateEvent(GetResponseSignalId(Process.GetCurrentProcess().Id));
responseEvent.Set();
break;
}
}
}
}
This application waits for input ControlledExitProgram.Ready.[pid]
and then runs some computation until it receives the input ControlledExitProgram.Ready.[pid]
.
There are two scenarios:
- Connect to the application with either ETW or EventPipe requesting data from RuntimeEventSource - provider name "System.Runtime", provider GUID "49592C0F-5A05-516D-AA4B-A64E02026C89". Then write
ControlledExitProgram.Ready.[pid]
to the standard input of the application. - At first write
ControlledExitProgram.Ready.[pid]
to the standard input of the application, and then connect to the application in the same way as in the 1st scenario.
Expected behavior
We successfully receive event counters from System.Runtime
provider in both scenarios.
Actual behavior
We do NOT receive event counters from System.Runtime
provider in the second scenario.
Regression?
Yes, everything was working smoothly until .NET 9 RC 1 (including all previous .NET preview versions).
Known Workarounds
Corresponding data is reported as a System.Runtime
meter via Metrics API, see RuntimeMetrics.cs.
So, it's technically possible to access the data. But it's unexpected and breaks some tooling.
Anyway, both approaches (with event counters and metrics) should work properly.
Configuration
.NET 9 RC 1, as far as I see, all supported platforms are affected.
Other information
No response