From a93f6984ff782cb02b07ba0ac2e9baec232e303d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Feb 2026 13:11:19 +0000 Subject: [PATCH 1/3] Initial plan From 6be2b02e77c9a88dbb9b44e38212ce4d7a3d8ef2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Feb 2026 13:16:05 +0000 Subject: [PATCH 2/3] Fix thread-safety issue in ProcessRunner StringBuilder access Co-authored-by: MihaZupan <25307628+MihaZupan@users.noreply.github.com> --- src/coreclr/tools/r2rtest/ProcessRunner.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/coreclr/tools/r2rtest/ProcessRunner.cs b/src/coreclr/tools/r2rtest/ProcessRunner.cs index 90792f1bc7cb2f..d61cba2bf22a45 100644 --- a/src/coreclr/tools/r2rtest/ProcessRunner.cs +++ b/src/coreclr/tools/r2rtest/ProcessRunner.cs @@ -116,6 +116,8 @@ public class ProcessRunner : IDisposable private readonly StringBuilder _outputCapture; + private readonly object _outputCaptureLock; + public ProcessRunner(ProcessInfo processInfo, int processIndex, int processCount, ReadyToRunJittedMethods jittedMethods, AutoResetEvent processExitEvent) { _processInfo = processInfo; @@ -172,6 +174,7 @@ public ProcessRunner(ProcessInfo processInfo, int processIndex, int processCount } _outputCapture = new StringBuilder(); + _outputCaptureLock = new object(); _outputHandler = new DataReceivedEventHandler(StandardOutputEventHandler); _process.OutputDataReceived += _outputHandler; @@ -284,7 +287,10 @@ private void StandardOutputEventHandler(object sender, DataReceivedEventArgs eve if (!string.IsNullOrEmpty(data)) { WriteLog(data); - _outputCapture.AppendLine(" " + data); + lock (_outputCaptureLock) + { + _outputCapture.AppendLine(" " + data); + } } } @@ -294,7 +300,10 @@ private void StandardErrorEventHandler(object sender, DataReceivedEventArgs even if (!string.IsNullOrEmpty(data)) { WriteLog(data); - _outputCapture.AppendLine("!! " + data); + lock (_outputCaptureLock) + { + _outputCapture.AppendLine("!! " + data); + } } } @@ -360,7 +369,10 @@ public bool IsAvailable(ref int progressIndex, ref int failureCount) WriteLog(failureMessage); Console.Error.WriteLine(failureMessage + $": {processSpec}"); - Console.Error.Write(_outputCapture.ToString()); + lock (_outputCaptureLock) + { + Console.Error.Write(_outputCapture.ToString()); + } } CleanupProcess(); From df031c7d738d22de755d0728086bdd53ad891344 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Feb 2026 13:22:22 +0000 Subject: [PATCH 3/3] Lock on StringBuilder itself and remove lock from ToString Co-authored-by: MihaZupan <25307628+MihaZupan@users.noreply.github.com> --- src/coreclr/tools/r2rtest/ProcessRunner.cs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/coreclr/tools/r2rtest/ProcessRunner.cs b/src/coreclr/tools/r2rtest/ProcessRunner.cs index d61cba2bf22a45..4afda3cae9c7a2 100644 --- a/src/coreclr/tools/r2rtest/ProcessRunner.cs +++ b/src/coreclr/tools/r2rtest/ProcessRunner.cs @@ -116,8 +116,6 @@ public class ProcessRunner : IDisposable private readonly StringBuilder _outputCapture; - private readonly object _outputCaptureLock; - public ProcessRunner(ProcessInfo processInfo, int processIndex, int processCount, ReadyToRunJittedMethods jittedMethods, AutoResetEvent processExitEvent) { _processInfo = processInfo; @@ -174,7 +172,6 @@ public ProcessRunner(ProcessInfo processInfo, int processIndex, int processCount } _outputCapture = new StringBuilder(); - _outputCaptureLock = new object(); _outputHandler = new DataReceivedEventHandler(StandardOutputEventHandler); _process.OutputDataReceived += _outputHandler; @@ -287,7 +284,7 @@ private void StandardOutputEventHandler(object sender, DataReceivedEventArgs eve if (!string.IsNullOrEmpty(data)) { WriteLog(data); - lock (_outputCaptureLock) + lock (_outputCapture) { _outputCapture.AppendLine(" " + data); } @@ -300,7 +297,7 @@ private void StandardErrorEventHandler(object sender, DataReceivedEventArgs even if (!string.IsNullOrEmpty(data)) { WriteLog(data); - lock (_outputCaptureLock) + lock (_outputCapture) { _outputCapture.AppendLine("!! " + data); } @@ -369,10 +366,7 @@ public bool IsAvailable(ref int progressIndex, ref int failureCount) WriteLog(failureMessage); Console.Error.WriteLine(failureMessage + $": {processSpec}"); - lock (_outputCaptureLock) - { - Console.Error.Write(_outputCapture.ToString()); - } + Console.Error.Write(_outputCapture.ToString()); } CleanupProcess();