summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Gianforcaro <bgianf@serenityos.org>2021-09-07 00:17:45 -0700
committerAndreas Kling <kling@serenityos.org>2021-09-07 13:16:01 +0200
commit0718afa773e72a9db1515409d5e9b4287c367dec (patch)
tree0a8946c023ae37d8615cfad6f676888ca4911806
parentf56bdd2bb77bc723bd63dc3f384e21a23b726151 (diff)
downloadserenity-0718afa773e72a9db1515409d5e9b4287c367dec.zip
Kernel: Track when a thread is in the middle of crashing
There are certain checks that we should skip if the system is crashing. The system can avoid stack overflow during crash, or even triple faulting while while handling issues that can causes recursive panics or aborts.
-rw-r--r--Kernel/Arch/x86/common/CPU.cpp5
-rw-r--r--Kernel/Panic.cpp6
-rw-r--r--Kernel/Thread.h4
3 files changed, 15 insertions, 0 deletions
diff --git a/Kernel/Arch/x86/common/CPU.cpp b/Kernel/Arch/x86/common/CPU.cpp
index 13fb019a75..d3d393320e 100644
--- a/Kernel/Arch/x86/common/CPU.cpp
+++ b/Kernel/Arch/x86/common/CPU.cpp
@@ -20,6 +20,11 @@ void __assertion_failed(const char* msg, const char* file, unsigned line, const
[[noreturn]] void abort()
{
+ // Avoid lock ranking checks on crashing paths, just try to get some debugging messages out.
+ auto thread = Thread::current();
+ if (thread)
+ thread->set_crashing();
+
// Switch back to the current process's page tables if there are any.
// Otherwise stack walking will be a disaster.
if (Process::has_current())
diff --git a/Kernel/Panic.cpp b/Kernel/Panic.cpp
index 635f197e99..83f9b47675 100644
--- a/Kernel/Panic.cpp
+++ b/Kernel/Panic.cpp
@@ -10,6 +10,7 @@
#include <Kernel/IO.h>
#include <Kernel/KSyms.h>
#include <Kernel/Panic.h>
+#include <Kernel/Thread.h>
namespace Kernel {
@@ -25,6 +26,11 @@ namespace Kernel {
void __panic(const char* file, unsigned int line, const char* function)
{
+ // Avoid lock ranking checks on crashing paths, just try to get some debugging messages out.
+ auto thread = Thread::current();
+ if (thread)
+ thread->set_crashing();
+
critical_dmesgln("at {}:{} in {}", file, line, function);
dump_backtrace(PrintToScreen::Yes);
if (kernel_command_line().boot_mode() == BootMode::SelfTest)
diff --git a/Kernel/Thread.h b/Kernel/Thread.h
index f2788e8758..6a5cd349e7 100644
--- a/Kernel/Thread.h
+++ b/Kernel/Thread.h
@@ -1186,6 +1186,9 @@ public:
void set_idle_thread() { m_is_idle_thread = true; }
bool is_idle_thread() const { return m_is_idle_thread; }
+ void set_crashing() { m_is_crashing = true; }
+ [[nodiscard]] bool is_crashing() const { return m_is_crashing; }
+
ALWAYS_INLINE u32 enter_profiler()
{
return m_nested_profiler_calls.fetch_add(1, AK::MemoryOrder::memory_order_acq_rel);
@@ -1343,6 +1346,7 @@ private:
bool m_initialized { false };
bool m_in_block { false };
bool m_is_idle_thread { false };
+ bool m_is_crashing { false };
Atomic<bool> m_have_any_unmasked_pending_signals { false };
Atomic<u32> m_nested_profiler_calls { 0 };