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

Code before:
            recordTraceProcess.WaitForExit(); // flush async output

            if (!File.Exists(traceFilePath))
            {
                Console.Error.WriteLine($"Expected trace file not found at `{traceFilePath}`");
                return -1;
            }

            using EventPipeEventSource source = new EventPipeEventSource(traceFilePath);
            if (!traceValidator(source))
            {
                Console.Error.WriteLine($"Trace file `{traceFilePath}` does not contain expected events.");
                UploadTraceFileFromHelix(traceFilePath, scenarioName);
                return -1;
            }

            return 100;
        }

        private static string ResolveRecordTracePath(string userEventsScenarioDir)
        {
            // In NativeAOT, Assembly.Location returns an empty string, so userEventsScenarioDir can be null or empty.
            // Fall back to the current process's main module path.
            if (string.IsNullOrEmpty(userEventsScenarioDir))
            {
                string? mainModuleFileName = Process.GetCurrentProcess().MainModule?.FileName;
                if (string.IsNullOrEmpty(mainModuleFileName))
                {
                    throw new InvalidOperationException("Unable to determine the test assembly path: Assembly.Location is empty and MainModule.FileName is unavailable.");
                }
                
                userEventsScenarioDir = Path.GetDirectoryName(mainModuleFileName);
                if (string.IsNullOrEmpty(userEventsScenarioDir))
                {
                    throw new InvalidOperationException($"Unable to determine the directory of the main module: {mainModuleFileName}");
                }
            }

            // scenario dir: .../tracing/userevents/<scenario>/<scenario>
            string usereventsRoot = Path.GetFullPath(Path.Combine(userEventsScenarioDir, "..", ".."));
            // common dir: .../tracing/userevents/common/userevents_common
            string commonDir = Path.Combine(usereventsRoot, "common", "userevents_common");
            string recordTracePath = Path.Combine(commonDir, "record-trace");
            return recordTracePath;
        }

        // Similar to IpcTraceTest.EnsureCleanEnvironment, but scoped to the provided diagnosticPortDir.
        // Check for zombie diagnostic IPC sockets left behind by previous runs and remove them.
        // If multiple sockets exist for a running PID, delete all but the newest.
        private static void EnsureCleanDiagnosticPorts(string diagnosticPortDir)
        {

Review comment (suggestion):
```suggestion
                string? mainModuleFileName = Environment.ProcessPath;
```

In the context of NativeAOT, they both return the same value (this is faster and produces less garbage).

Code after:
                    Console.Error.WriteLine($"[tracee] {args.Data}");
                }
            };
            traceeProcess.BeginErrorReadLine();

            Console.WriteLine($"Waiting for tracee process to exit...");
            if (!traceeProcess.HasExited && !traceeProcess.WaitForExit(traceeExitTimeout))
            {
                Console.WriteLine($"Tracee process did not exit within the {traceeExitTimeout}ms timeout, killing it.");
                traceeProcess.Kill();
            }
            traceeProcess.WaitForExit(); // flush async output

            if (!recordTraceProcess.HasExited)
            {
                // Until record-trace supports duration, the only way to stop it is to send SIGINT (ctrl+c)
                Console.WriteLine($"Stopping record-trace with SIGINT.");
                Kill(recordTraceProcess.Id, SIGINT);
                Console.WriteLine($"Waiting for record-trace to exit...");
                if (!recordTraceProcess.WaitForExit(recordTraceExitTimeout))
                {
                    // record-trace needs to stop gracefully to generate the trace file
                    Console.WriteLine($"record-trace did not exit within the {recordTraceExitTimeout}ms timeout, killing it.");
                    recordTraceProcess.Kill();
                }
            }
            else
            {
                Console.WriteLine($"record-trace unexpectedly exited without SIGINT with code {recordTraceProcess.ExitCode}.");
            }
            recordTraceProcess.WaitForExit(); // flush async output

            if (!File.Exists(traceFilePath))
            {
                Console.Error.WriteLine($"Expected trace file not found at `{traceFilePath}`");
                return -1;
            }

            using EventPipeEventSource source = new EventPipeEventSource(traceFilePath);
            if (!traceValidator(source))
            {
                Console.Error.WriteLine($"Trace file `{traceFilePath}` does not contain expected events.");
                UploadTraceFileFromHelix(traceFilePath, scenarioName);
                return -1;
            }

            return 100;
        }

        private static string ResolveRecordTracePath(string userEventsScenarioDir)
        {