From 83fdad25edfec1c8668afdff1268129e5181d78a Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 6 Aug 2019 19:43:07 +0200 Subject: [PATCH] Kernel: For signal-killed threads, dump backtrace from finalizer thread Instead of dumping the dying thread's backtrace in the signal handling code, wait until we're finalizing the thread. Since signalling happens during scheduling, the less work we do there the better. Basically the less that happens during a scheduler pass the better. :^) --- Kernel/Thread.cpp | 18 +++++++++++++----- Kernel/Thread.h | 4 ++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index 4edf777343..1b836a0a30 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -171,6 +171,9 @@ void Thread::finalize() dbgprintf("Finalizing Thread %u in %s(%u)\n", tid(), m_process.name().characters(), pid()); set_state(Thread::State::Dead); + if (m_dump_backtrace_on_finalization) + dbg() << backtrace_impl(); + if (this == &m_process.main_thread()) { m_process.finalize(); return; @@ -337,11 +340,11 @@ ShouldUnblockThread Thread::dispatch_signal(u8 signal) case DefaultSignalAction::Stop: set_state(Stopped); return ShouldUnblockThread::No; - case DefaultSignalAction::DumpCore: { - ProcessInspectionHandle handle(process()); - dbg() << "Dumping \"Core\" for " << process(); - dbg() << process().backtrace(handle); - } + case DefaultSignalAction::DumpCore: + process().for_each_thread([](auto& thread) { + thread.set_dump_backtrace_on_finalization(); + return IterationDecision::Continue; + }); [[fallthrough]]; case DefaultSignalAction::Terminate: m_process.terminate_due_to_signal(signal); @@ -568,6 +571,11 @@ void Thread::set_state(State new_state) } String Thread::backtrace(ProcessInspectionHandle&) const +{ + return backtrace_impl(); +} + +String Thread::backtrace_impl() const { auto& process = const_cast(this->process()); ProcessPagingScope paging_scope(process); diff --git a/Kernel/Thread.h b/Kernel/Thread.h index 4bfa72e11a..89a5ac29a9 100644 --- a/Kernel/Thread.h +++ b/Kernel/Thread.h @@ -281,6 +281,8 @@ public: void send_signal(u8 signal, Process* sender); void consider_unblock(time_t now_sec, long now_usec); + void set_dump_backtrace_on_finalization() { m_dump_backtrace_on_finalization = true; } + ShouldUnblockThread dispatch_one_pending_signal(); ShouldUnblockThread dispatch_signal(u8 signal); bool has_unmasked_pending_signals() const; @@ -315,6 +317,7 @@ private: private: friend class SchedulerData; + String backtrace_impl() const; Process& m_process; int m_tid { -1 }; TSS32 m_tss; @@ -335,6 +338,7 @@ private: FPUState* m_fpu_state { nullptr }; State m_state { Invalid }; bool m_has_used_fpu { false }; + bool m_dump_backtrace_on_finalization { false }; void block_helper(); };