diff --git a/src/libraries/System.Runtime/tests/System/ExitCodeTests.Unix.cs b/src/libraries/System.Runtime/tests/System/ExitCodeTests.Unix.cs index 9fd7ab4f461a98..bd7cf68e87c366 100644 --- a/src/libraries/System.Runtime/tests/System/ExitCodeTests.Unix.cs +++ b/src/libraries/System.Runtime/tests/System/ExitCodeTests.Unix.cs @@ -16,7 +16,6 @@ public class ExitCodeTests private static extern int kill(int pid, int sig); [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/31656", TestRuntimes.Mono)] [InlineData(null)] [InlineData(0)] [InlineData(42)] diff --git a/src/mono/mono/metadata/gc.c b/src/mono/mono/metadata/gc.c index f5f74cfd5073c9..e1495c70729a33 100644 --- a/src/mono/mono/metadata/gc.c +++ b/src/mono/mono/metadata/gc.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +64,8 @@ static gboolean gc_disabled; static gboolean finalizing_root_domain; +extern gboolean mono_term_signaled; + gboolean mono_log_finalizers; gboolean mono_do_not_finalize; static volatile gboolean suspend_finalizers; @@ -879,6 +882,7 @@ finalizer_thread (gpointer unused) mono_hazard_pointer_install_free_queue_size_callback (hazard_free_queue_is_too_big); while (!finished) { + /* Wait to be notified that there's at least one * finaliser to run */ @@ -892,6 +896,12 @@ finalizer_thread (gpointer unused) } wait = TRUE; + /* Just in case we've received a SIGTERM */ + if (mono_term_signaled) { + mono_runtime_try_shutdown(); + exit(mono_environment_exitcode_get()); + } + mono_thread_info_set_flags (MONO_THREAD_INFO_FLAGS_NONE); /* The Finalizer thread doesn't initialize during creation because base managed diff --git a/src/mono/mono/mini/mini-posix.c b/src/mono/mono/mini/mini-posix.c index be8f83d396872d..3f866b5ec73fc1 100644 --- a/src/mono/mono/mini/mini-posix.c +++ b/src/mono/mono/mini/mini-posix.c @@ -390,6 +390,8 @@ mono_runtime_posix_install_handlers (void) sigaddset (&signal_set, SIGFPE); add_signal_handler (SIGQUIT, sigquit_signal_handler, SA_RESTART); sigaddset (&signal_set, SIGQUIT); + add_signal_handler (SIGTERM, mono_sigterm_signal_handler, SA_RESTART); + sigaddset (&signal_set, SIGTERM); add_signal_handler (SIGILL, mono_crashing_signal_handler, 0); sigaddset (&signal_set, SIGILL); add_signal_handler (SIGBUS, mono_sigsegv_signal_handler, 0); diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index cd7117dde4143e..ef5802d13822d6 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -118,6 +118,7 @@ const char *mono_build_date; gboolean mono_do_signal_chaining; gboolean mono_do_crash_chaining; int mini_verbose = 0; +gboolean mono_term_signaled = FALSE; /* * This flag controls whenever the runtime uses LLVM for JIT compilation, and whenever @@ -3628,6 +3629,17 @@ MONO_SIG_HANDLER_FUNC (, mono_crashing_signal_handler) } } +MONO_SIG_HANDLER_FUNC (, mono_sigterm_signal_handler) +{ + mono_environment_exitcode_set(128+SIGTERM); /* Set default exit code */ + + mono_term_signaled = TRUE; + + mono_gc_finalize_notify (); + + mono_chain_signal (MONO_SIG_HANDLER_PARAMS); +} + #if defined(MONO_ARCH_USE_SIGACTION) || defined(HOST_WIN32) #define HAVE_SIG_INFO diff --git a/src/mono/mono/mini/mini-runtime.h b/src/mono/mono/mini/mini-runtime.h index 16299ff4020527..09018b9333fd8f 100644 --- a/src/mono/mono/mini/mini-runtime.h +++ b/src/mono/mono/mini/mini-runtime.h @@ -671,6 +671,7 @@ void MONO_SIG_HANDLER_SIGNATURE (mono_sigfpe_signal_handler) ; void MONO_SIG_HANDLER_SIGNATURE (mono_crashing_signal_handler) ; void MONO_SIG_HANDLER_SIGNATURE (mono_sigsegv_signal_handler); void MONO_SIG_HANDLER_SIGNATURE (mono_sigint_signal_handler) ; +void MONO_SIG_HANDLER_SIGNATURE (mono_sigterm_signal_handler) ; gboolean MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal); #if defined (HOST_WASM) diff --git a/src/mono/mono/mini/mini-windows.c b/src/mono/mono/mini/mini-windows.c index c678f4c4594c45..744d4fa460e818 100644 --- a/src/mono/mono/mini/mini-windows.c +++ b/src/mono/mono/mini/mini-windows.c @@ -189,6 +189,7 @@ mono_runtime_install_handlers (void) win32_seh_set_handler(SIGFPE, mono_sigfpe_signal_handler); win32_seh_set_handler(SIGILL, mono_crashing_signal_handler); win32_seh_set_handler(SIGSEGV, mono_sigsegv_signal_handler); + win32_seh_set_handler(SIGTERM, mono_sigterm_signal_handler); if (mini_debug_options.handle_sigint) win32_seh_set_handler(SIGINT, mono_sigint_signal_handler); #endif