From 70ccdb300bdfb20d465f7e1933f719b707e0f924 Mon Sep 17 00:00:00 2001 From: Daniel Bertalan Date: Sat, 5 Mar 2022 21:01:06 +0100 Subject: [PATCH] Kernel: Panic if the init process dies If init crashes, all other userspace processes exit too, thus rendering the system unusable. Previously, the kernel would still keep running even without a userland, showing just a black screen without any indication of the issue. We now panic the kernel, which shows a message on the console. In the case of the CI runners, it shuts down the virtual machine, so we don't have to wait for the 1 hour timeout if an issue arises with SystemServer. --- Kernel/Process.cpp | 6 ++++++ Kernel/init.cpp | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index aede604637..135e7ebcb8 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,8 @@ namespace Kernel { static void create_signal_trampoline(); +extern ProcessID g_init_pid; + RecursiveSpinlock g_profiling_lock; static Atomic next_pid; static Singleton> s_all_instances; @@ -609,6 +612,9 @@ void Process::finalize() if (veil_state() == VeilState::Dropped) dbgln("\x1b[01;31mProcess '{}' exited with the veil left open\x1b[0m", name()); + if (g_init_pid != 0 && pid() == g_init_pid) + PANIC("Init process quit unexpectedly. Exit code: {}", m_protected_values.termination_status); + if (is_dumpable()) { if (m_should_generate_coredump) { auto result = dump_core(); diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 4c814cc9c2..3e11be2bf1 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -97,6 +97,8 @@ extern "C" [[noreturn]] void init(BootInfo const&); READONLY_AFTER_INIT VirtualConsole* tty0; +ProcessID g_init_pid { 0 }; + static Processor s_bsp_processor; // global but let's keep it "private" // SerenityOS Kernel C++ entry point :^) @@ -374,6 +376,8 @@ void init_stage2(void*) if (init_or_error.is_error()) PANIC("init_stage2: Error spawning init process: {}", init_or_error.error()); + g_init_pid = init_or_error.value()->pid(); + thread->set_priority(THREAD_PRIORITY_HIGH); if (boot_profiling) {