Repository: dotnet/runtime
File: src/tests/tracing/userevents/common/UserEventsTestRunner.cs (C#)

Code before:
            ProcessStartInfo traceeStartInfo = new();
            traceeStartInfo.FileName = Environment.ProcessPath 
                ?? throw new InvalidOperationException("Environment.ProcessPath is null");
            
            // NativeAOT tests run the native executable directly.
            // CoreCLR tests run through corerun which loads the managed assembly.
            if (isNativeAot)
            {
                traceeStartInfo.Arguments = "tracee";
            }
            else
            {
                // For CoreCLR, construct the path to the assembly
                string assemblyPath = Path.Combine(userEventsScenarioDir, $"{scenarioName}.dll");
                traceeStartInfo.Arguments = $"{assemblyPath} tracee";
            }
            
            traceeStartInfo.WorkingDirectory = userEventsScenarioDir;
            traceeStartInfo.RedirectStandardOutput = true;
            traceeStartInfo.RedirectStandardError = true;

            // record-trace currently only searches /tmp/ for diagnostic ports https://github.com/microsoft/one-collect/issues/183
            string diagnosticPortDir = "/tmp";
            traceeStartInfo.Environment["TMPDIR"] = diagnosticPortDir;

            // Note: record-trace uses perfmap/doublemapper to discover .NET process PIDs and their diagnostic ports.
            // NativeAOT apps do not use doublemapping, so they will not be discovered by record-trace even with TMPDIR set.
            // See https://github.com/microsoft/one-collect/issues/226 for details.

            // TMPDIR is configured on Helix, but the diagnostic port is created outside of Helix's default temp datadisk path.
            // The diagnostic port should be automatically cleaned up when the tracee shuts down, but zombie sockets can be left
            // behind after catastrophic exits. Clean them before launching the tracee to avoid deleting sockets from a reused PID.
            // When https://github.com/microsoft/one-collect/issues/183 is fixed, this and the above TMPDIR should be removed.
            EnsureCleanDiagnosticPorts(diagnosticPortDir);

            Console.WriteLine($"Starting tracee process: {traceeStartInfo.FileName} {traceeStartInfo.Arguments}");
            using Process traceeProcess = Process.Start(traceeStartInfo);
            int traceePid = traceeProcess.Id;
            Console.WriteLine($"Tracee process started with PID: {traceePid}");
            traceeProcess.OutputDataReceived += (_, args) =>
            {
                if (!string.IsNullOrEmpty(args.Data))
                {
                    Console.WriteLine($"[tracee] {args.Data}");
                }
            };
            traceeProcess.BeginOutputReadLine();
            traceeProcess.ErrorDataReceived += (_, args) =>
            {
                if (!string.IsNullOrEmpty(args.Data))
                {

Review comment (bug):
@copilot looks like the original issue in https://github.com/dotnet/runtime/pull/123541 has been fixed, so now we are hitting the expected test failure here. Can you re-add the `src/tests/tracing/userevents/Directory.Build.props` file and move this comment into there

Code after:
                }
            };
            recordTraceProcess.BeginErrorReadLine();
            Console.WriteLine($"record-trace started with PID: {recordTraceProcess.Id}");

            ProcessStartInfo traceeStartInfo = new();
            traceeStartInfo.FileName = Environment.ProcessPath
                ?? throw new InvalidOperationException("Environment.ProcessPath is null");

            // NativeAOT tests run the native executable directly.
            // CoreCLR tests run through corerun which loads the managed assembly.
            if (isNativeAot)
            {
                traceeStartInfo.ArgumentList.Add("tracee");
            }
            else
            {
                // For CoreCLR, construct the path to the assembly
                string assemblyPath = Path.Combine(userEventsScenarioDir, $"{scenarioName}.dll");
                traceeStartInfo.ArgumentList.Add(assemblyPath);
                traceeStartInfo.ArgumentList.Add("tracee");
            }

            traceeStartInfo.WorkingDirectory = userEventsScenarioDir;
            traceeStartInfo.RedirectStandardOutput = true;
            traceeStartInfo.RedirectStandardError = true;

            // record-trace currently only searches /tmp/ for diagnostic ports https://github.com/microsoft/one-collect/issues/183
            string diagnosticPortDir = "/tmp";
            traceeStartInfo.Environment["TMPDIR"] = diagnosticPortDir;

            // TMPDIR is configured on Helix, but the diagnostic port is created outside of Helix's default temp datadisk path.
            // The diagnostic port should be automatically cleaned up when the tracee shuts down, but zombie sockets can be left
            // behind after catastrophic exits. Clean them before launching the tracee to avoid deleting sockets from a reused PID.
            // When https://github.com/microsoft/one-collect/issues/183 is fixed, this and the above TMPDIR should be removed.
            EnsureCleanDiagnosticPorts(diagnosticPortDir);

            Console.WriteLine($"Starting tracee process: {traceeStartInfo.FileName} {string.Join(" ", traceeStartInfo.ArgumentList)}");
            using Process traceeProcess = Process.Start(traceeStartInfo);
            int traceePid = traceeProcess.Id;
            Console.WriteLine($"Tracee process started with PID: {traceePid}");
            traceeProcess.OutputDataReceived += (_, args) =>
            {
                if (!string.IsNullOrEmpty(args.Data))
                {
                    Console.WriteLine($"[tracee] {args.Data}");
                }
            };
            traceeProcess.BeginOutputReadLine();
            traceeProcess.ErrorDataReceived += (_, args) =>
            {