From 4ec351d454238b910defbbf41b4155997950aad4 Mon Sep 17 00:00:00 2001 From: tmat Date: Wed, 11 Jun 2025 12:17:31 -0700 Subject: [PATCH 1/6] Do not use SIGTERM --- .../dotnet-watch/Internal/ProcessRunner.cs | 5 ++- .../HotReload/ApplyDeltaTests.cs | 40 ++++++++++--------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs b/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs index 6551d37c8a06..9637a70f2e77 100644 --- a/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs +++ b/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs @@ -310,7 +310,10 @@ private static void TerminateUnixProcess(ProcessState state, IReporter reporter) [DllImport("libc", SetLastError = true, EntryPoint = "kill")] static extern int sys_kill(int pid, int sig); - var result = sys_kill(state.ProcessId, state.ForceExit ? SIGKILL : SIGTERM); + // SIGTERM no longer works on Linux https://github.com/dotnet/sdk/issues/49307 + // state.ForceExit ? SIGKILL : SIGTERM + + var result = sys_kill(state.ProcessId, SIGKILL); if (result != 0) { var error = Marshal.GetLastPInvokeError(); diff --git a/test/dotnet-watch.Tests/HotReload/ApplyDeltaTests.cs b/test/dotnet-watch.Tests/HotReload/ApplyDeltaTests.cs index 2fef1c0e6dff..cb3c286b74bb 100644 --- a/test/dotnet-watch.Tests/HotReload/ApplyDeltaTests.cs +++ b/test/dotnet-watch.Tests/HotReload/ApplyDeltaTests.cs @@ -420,7 +420,7 @@ class AppUpdateHandler } } - [Theory(Skip = "https://github.com/dotnet/sdk/issues/45299")] + [Theory] [CombinatorialData] public async Task BlazorWasm(bool projectSpecifiesCapabilities) { @@ -502,7 +502,7 @@ public async Task BlazorWasm_MSBuildWarning() await App.AssertWaitingForChanges(); } - [Fact(Skip = "https://github.com/dotnet/sdk/issues/49307")] + [Fact] public async Task BlazorWasm_Restart() { var testAsset = TestAssets.CopyTestAsset("WatchBlazorWasm") @@ -810,17 +810,19 @@ public async Task Aspire() await App.AssertOutputLineStartsWith(MessageDescriptor.FixBuildError, failure: _ => false); + // SIGTERM no longer works on Linux https://github.com/dotnet/sdk/issues/49307 + // We don't have means to gracefully terminate process on Windows, see https://github.com/dotnet/runtime/issues/109432 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + // if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { App.AssertOutputContains($"dotnet watch ❌ [WatchAspire.ApiService ({tfm})] Exited with error code -1"); } - else - { - // Unix process may return exit code = 128 + SIGTERM - // Exited with error code 143 - App.AssertOutputContains($"[WatchAspire.ApiService ({tfm})] Exited"); - } + //else + //{ + // // Unix process may return exit code = 128 + SIGTERM + // // Exited with error code 143 + // App.AssertOutputContains($"[WatchAspire.ApiService ({tfm})] Exited"); + //} App.AssertOutputContains($"dotnet watch ⌚ Building {serviceProjectPath} ..."); App.AssertOutputContains("error CS0246: The type or namespace name 'WeatherForecast' could not be found"); @@ -834,7 +836,7 @@ public async Task Aspire() await App.AssertOutputLineStartsWith($"dotnet watch ⌚ [WatchAspire.ApiService ({tfm})] Capabilities"); App.AssertOutputContains($"dotnet watch 🔨 Build succeeded: {serviceProjectPath}"); - App.AssertOutputContains("dotnet watch 🔥 Project baselines updated."); + App.AssertOutputContains("dotnet watch 🔥 Projects rebuilt"); App.AssertOutputContains($"dotnet watch ⭐ Starting project: {serviceProjectPath}"); // Note: sending Ctrl+C via standard input is not the same as sending real Ctrl+C. @@ -843,19 +845,21 @@ public async Task Aspire() await App.AssertOutputLineStartsWith("dotnet watch 🛑 Shutdown requested. Press Ctrl+C again to force exit."); + // SIGTERM no longer works on Linux https://github.com/dotnet/sdk/issues/49307 + // We don't have means to gracefully terminate process on Windows, see https://github.com/dotnet/runtime/issues/109432 - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + // if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { await App.AssertOutputLineStartsWith($"dotnet watch ❌ [WatchAspire.ApiService ({tfm})] Exited with error code -1"); await App.AssertOutputLineStartsWith($"dotnet watch ❌ [WatchAspire.AppHost ({tfm})] Exited with error code -1"); } - else - { - // Unix process may return exit code = 128 + SIGTERM - // Exited with error code 143 - await App.AssertOutputLine(line => line.Contains($"[WatchAspire.ApiService ({tfm})] Exited")); - await App.AssertOutputLine(line => line.Contains($"[WatchAspire.AppHost ({tfm})] Exited")); - } + //else + //{ + // // Unix process may return exit code = 128 + SIGTERM + // // Exited with error code 143 + // await App.AssertOutputLine(line => line.Contains($"[WatchAspire.ApiService ({tfm})] Exited")); + // await App.AssertOutputLine(line => line.Contains($"[WatchAspire.AppHost ({tfm})] Exited")); + //} await App.AssertOutputLineStartsWith("dotnet watch ⭐ Waiting for server to shutdown ..."); From 16136cf2e3420f73dd5e3faa46eb39e8aa9818ba Mon Sep 17 00:00:00 2001 From: tmat Date: Wed, 11 Jun 2025 12:21:13 -0700 Subject: [PATCH 2/6] Fix --- .../HotReload/ApplyDeltaTests.cs | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/test/dotnet-watch.Tests/HotReload/ApplyDeltaTests.cs b/test/dotnet-watch.Tests/HotReload/ApplyDeltaTests.cs index cb3c286b74bb..2d687e1e7263 100644 --- a/test/dotnet-watch.Tests/HotReload/ApplyDeltaTests.cs +++ b/test/dotnet-watch.Tests/HotReload/ApplyDeltaTests.cs @@ -810,19 +810,21 @@ public async Task Aspire() await App.AssertOutputLineStartsWith(MessageDescriptor.FixBuildError, failure: _ => false); - // SIGTERM no longer works on Linux https://github.com/dotnet/sdk/issues/49307 - // We don't have means to gracefully terminate process on Windows, see https://github.com/dotnet/runtime/issues/109432 - // if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { App.AssertOutputContains($"dotnet watch ❌ [WatchAspire.ApiService ({tfm})] Exited with error code -1"); } - //else - //{ - // // Unix process may return exit code = 128 + SIGTERM - // // Exited with error code 143 - // App.AssertOutputContains($"[WatchAspire.ApiService ({tfm})] Exited"); - //} + else + { + App.AssertOutputContains($"dotnet watch ❌ [WatchAspire.ApiService ({tfm})] Exited"); + + // TODO: SIGTERM no longer works on Linux https://github.com/dotnet/sdk/issues/49307 + // Unix process may return exit code = 128 + SIGTERM + + // Exited with error code 143 + // App.AssertOutputContains($"[WatchAspire.ApiService ({tfm})] Exited"); + } App.AssertOutputContains($"dotnet watch ⌚ Building {serviceProjectPath} ..."); App.AssertOutputContains("error CS0246: The type or namespace name 'WeatherForecast' could not be found"); @@ -848,18 +850,23 @@ public async Task Aspire() // SIGTERM no longer works on Linux https://github.com/dotnet/sdk/issues/49307 // We don't have means to gracefully terminate process on Windows, see https://github.com/dotnet/runtime/issues/109432 - // if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { await App.AssertOutputLineStartsWith($"dotnet watch ❌ [WatchAspire.ApiService ({tfm})] Exited with error code -1"); await App.AssertOutputLineStartsWith($"dotnet watch ❌ [WatchAspire.AppHost ({tfm})] Exited with error code -1"); } - //else - //{ - // // Unix process may return exit code = 128 + SIGTERM - // // Exited with error code 143 - // await App.AssertOutputLine(line => line.Contains($"[WatchAspire.ApiService ({tfm})] Exited")); - // await App.AssertOutputLine(line => line.Contains($"[WatchAspire.AppHost ({tfm})] Exited")); - //} + else + { + // TODO: SIGTERM no longer works on Linux https://github.com/dotnet/sdk/issues/49307 + + await App.AssertOutputLineStartsWith($"dotnet watch ❌ [WatchAspire.ApiService ({tfm})] Exited"); + await App.AssertOutputLineStartsWith($"dotnet watch ❌ [WatchAspire.AppHost ({tfm})] Exited"); + + // Unix process may return exit code = 128 + SIGTERM + // Exited with error code 143 + // await App.AssertOutputLine(line => line.Contains($"[WatchAspire.ApiService ({tfm})] Exited")); + // await App.AssertOutputLine(line => line.Contains($"[WatchAspire.AppHost ({tfm})] Exited")); + } await App.AssertOutputLineStartsWith("dotnet watch ⭐ Waiting for server to shutdown ..."); From dbcfb449e4692c22ec982f8dbd79642d204c328b Mon Sep 17 00:00:00 2001 From: tmat Date: Wed, 11 Jun 2025 18:35:52 -0700 Subject: [PATCH 3/6] Kill --- .../dotnet-watch/Internal/ProcessRunner.cs | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs b/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs index 9637a70f2e77..1aa246d95293 100644 --- a/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs +++ b/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs @@ -305,20 +305,21 @@ private static void TerminateWindowsProcess(Process process, ProcessState state, process.Kill(); } - private static void TerminateUnixProcess(ProcessState state, IReporter reporter) + private static void TerminateUnixProcess(Process process, ProcessState state, IReporter reporter) { - [DllImport("libc", SetLastError = true, EntryPoint = "kill")] - static extern int sys_kill(int pid, int sig); + // Signals no longer work on Linux https://github.com/dotnet/sdk/issues/49307 - // SIGTERM no longer works on Linux https://github.com/dotnet/sdk/issues/49307 - // state.ForceExit ? SIGKILL : SIGTERM + //[DllImport("libc", SetLastError = true, EntryPoint = "kill")] + //static extern int sys_kill(int pid, int sig); - var result = sys_kill(state.ProcessId, SIGKILL); - if (result != 0) - { - var error = Marshal.GetLastPInvokeError(); - reporter.Verbose($"Error while sending SIGTERM to process {state.ProcessId}: {Marshal.GetPInvokeErrorMessage(error)} (code {error})."); - } + //var result = sys_kill(state.ProcessId, state.ForceExit ? SIGKILL : SIGTERM); + //if (result != 0) + //{ + // var error = Marshal.GetLastPInvokeError(); + // reporter.Verbose($"Error while sending SIGTERM to process {state.ProcessId}: {Marshal.GetPInvokeErrorMessage(error)} (code {error})."); + //} + + process.Kill(); } } } From 3e7cf3350898d1c1ca7ffb5b2098000d83f29722 Mon Sep 17 00:00:00 2001 From: tmat Date: Wed, 11 Jun 2025 18:36:10 -0700 Subject: [PATCH 4/6] Fix --- src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs b/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs index 1aa246d95293..c22598937542 100644 --- a/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs +++ b/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs @@ -257,7 +257,7 @@ private static void TerminateProcess(Process process, ProcessState state, IRepor } else { - TerminateUnixProcess(state, reporter); + TerminateUnixProcess(process, state, reporter); } reporter.Verbose($"Process {state.ProcessId} killed."); From 6902c7299d15865ae4d3bc4b134a5b0a3cf9ccff Mon Sep 17 00:00:00 2001 From: tmat Date: Thu, 12 Jun 2025 08:50:47 -0700 Subject: [PATCH 5/6] SKip --- test/dotnet-watch.Tests/HotReload/ApplyDeltaTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/dotnet-watch.Tests/HotReload/ApplyDeltaTests.cs b/test/dotnet-watch.Tests/HotReload/ApplyDeltaTests.cs index 2d687e1e7263..b4a23558560a 100644 --- a/test/dotnet-watch.Tests/HotReload/ApplyDeltaTests.cs +++ b/test/dotnet-watch.Tests/HotReload/ApplyDeltaTests.cs @@ -757,7 +757,7 @@ public static void PrintDirectoryName([CallerFilePathAttribute] string filePath await App.AssertOutputLineStartsWith("> NewSubdir"); } - [Fact] + [Fact(Skip = "https://github.com/dotnet/sdk/issues/49307")] public async Task Aspire() { var tfm = ToolsetInfo.CurrentTargetFramework; From eaab8f1d58084d9017a1dc9edb85d85271bbb82d Mon Sep 17 00:00:00 2001 From: tmat Date: Thu, 12 Jun 2025 08:54:22 -0700 Subject: [PATCH 6/6] Fix --- src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs b/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs index c22598937542..e53942a662bc 100644 --- a/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs +++ b/src/BuiltInTools/dotnet-watch/Internal/ProcessRunner.cs @@ -319,7 +319,7 @@ private static void TerminateUnixProcess(Process process, ProcessState state, IR // reporter.Verbose($"Error while sending SIGTERM to process {state.ProcessId}: {Marshal.GetPInvokeErrorMessage(error)} (code {error})."); //} - process.Kill(); + process.Kill(entireProcessTree: true); } } }