diff --git a/src/SOS/SOS.UnitTests/SOSRunner.cs b/src/SOS/SOS.UnitTests/SOSRunner.cs index 4d92aff541..647bb08fb7 100644 --- a/src/SOS/SOS.UnitTests/SOSRunner.cs +++ b/src/SOS/SOS.UnitTests/SOSRunner.cs @@ -378,9 +378,10 @@ public static async Task CreateDump(TestInformation information) if (pipeServer != null) { dotnetDumpOutputHelper.WriteLine("Waiting for connection on pipe {0}", pipeName); - CancellationTokenSource source = new(TimeSpan.FromMinutes(5)); + using CancellationTokenSource source = new(TimeSpan.FromMinutes(5)); // Wait for debuggee to connect/write to pipe or if the process exits on some other failure/abnormally + // TODO: This is a resiliency issue - we'll try to collect the dump even if the debuggee fails to connect. await Task.WhenAny(pipeServer.WaitForConnectionAsync(source.Token), processRunner.WaitForExit()); } diff --git a/src/tests/CommonTestRunner/TestRunner.cs b/src/tests/CommonTestRunner/TestRunner.cs index a552385a6a..730dac25d1 100644 --- a/src/tests/CommonTestRunner/TestRunner.cs +++ b/src/tests/CommonTestRunner/TestRunner.cs @@ -245,8 +245,16 @@ public async Task WaitForTracee() WriteLine("WaitForTracee"); try { - CancellationTokenSource source = new(TimeSpan.FromMinutes(2)); - await _pipeServer.WaitForConnectionAsync(source.Token).ConfigureAwait(false); + using CancellationTokenSource source = new(TimeSpan.FromMinutes(2)); + Task processDeath = _runner.WaitForExit(); + Task traceeReady = _pipeServer.WaitForConnectionAsync(source.Token); + Task doneTask = await Task.WhenAny(processDeath, traceeReady).WaitAsync(source.Token).ConfigureAwait(false); + + source.Cancel(); + if (doneTask == processDeath) + { + Trace.TraceWarning($"WaitForTracee: process {Pid} exited without sending the event"); + } WriteLine("WaitForTracee: DONE"); } catch (Exception ex) when (ex is TaskCanceledException or OperationCanceledException) diff --git a/src/tests/DbgShim.UnitTests/DebuggeeInfo.cs b/src/tests/DbgShim.UnitTests/DebuggeeInfo.cs index b60e30ed6c..48588a6c64 100644 --- a/src/tests/DbgShim.UnitTests/DebuggeeInfo.cs +++ b/src/tests/DbgShim.UnitTests/DebuggeeInfo.cs @@ -71,9 +71,21 @@ public async Task WaitForDebuggee() } try { - CancellationTokenSource source = new(TimeSpan.FromMinutes(5)); + using CancellationTokenSource source = new(TimeSpan.FromMinutes(5)); Trace.TraceInformation($"DebuggeeInfo.WaitForDebuggee: waiting {ProcessId}"); - await _pipeServer.WaitForConnectionAsync(source.Token); + + Task processDeath = _process.WaitForExitAsync(source.Token); + Task debuggeeReady = _pipeServer.WaitForConnectionAsync(source.Token); + Task doneTask = await Task.WhenAny(processDeath, debuggeeReady).WaitAsync(source.Token); + + source.Cancel(); + + if (doneTask == processDeath) + { + Trace.TraceWarning($"DebuggeeInfo.WaitForDebuggee: process {ProcessId} exited"); + return false; + } + Trace.TraceInformation($"DebuggeeInfo.WaitForDebuggee: after wait {ProcessId}"); } catch (Exception ex) when (ex is TaskCanceledException or OperationCanceledException)