Kernel: Show more (b)locking info when dumping the process list

This commit is contained in:
Tim Schumacher 2022-08-25 12:18:16 +02:00 committed by Andreas Kling
parent 47af812a23
commit 2bf5052608
Notes: sideshowbarker 2024-07-17 07:43:05 +09:00
2 changed files with 49 additions and 5 deletions

View File

@ -564,6 +564,17 @@ void dump_thread_list(bool with_stack_traces)
thread.times_scheduled());
break;
}
if (thread.state() == Thread::State::Blocked && thread.blocking_mutex()) {
dmesgln(" Blocking on Mutex {:#x} ({})", thread.blocking_mutex(), thread.blocking_mutex()->name());
}
if (thread.state() == Thread::State::Blocked && thread.blocker()) {
dmesgln(" Blocking on Blocker {:#x}", thread.blocker());
}
#if LOCK_DEBUG
thread.for_each_held_lock([](auto const& entry) {
dmesgln(" Holding lock {:#x} ({}) at {}", entry.lock, entry.lock->name(), entry.lock_location);
});
#endif
if (with_stack_traces) {
auto trace_or_error = thread.backtrace();
if (!trace_or_error.is_error()) {

View File

@ -1154,6 +1154,22 @@ public:
ErrorOr<NonnullOwnPtr<KString>> backtrace();
Blocker const* blocker() const { return m_blocker; };
Kernel::Mutex const* blocking_mutex() const { return m_blocking_mutex; }
#if LOCK_DEBUG
struct HoldingLockInfo {
Mutex* lock;
LockLocation lock_location;
unsigned count;
};
template<IteratorFunction<HoldingLockInfo const&> Callback>
void for_each_held_lock(Callback);
template<VoidFunction<HoldingLockInfo const&> Callback>
void for_each_held_lock(Callback);
#endif
private:
Thread(NonnullLockRefPtr<Process>, NonnullOwnPtr<Memory::Region>, NonnullLockRefPtr<Timer>, NonnullOwnPtr<KString>);
@ -1266,11 +1282,6 @@ private:
IntrusiveListNode<Thread> m_big_lock_blocked_threads_list_node;
#if LOCK_DEBUG
struct HoldingLockInfo {
Mutex* lock;
LockLocation lock_location;
unsigned count;
};
Atomic<u32> m_holding_locks { 0 };
Spinlock m_holding_locks_lock { LockRank::None };
Vector<HoldingLockInfo> m_holding_locks_list;
@ -1386,6 +1397,28 @@ inline IterationDecision Thread::for_each_in_state(State state, Callback callbac
});
}
#if LOCK_DEBUG
template<IteratorFunction<Thread::HoldingLockInfo const&> Callback>
inline void Thread::for_each_held_lock(Callback callback)
{
SpinlockLocker list_lock(m_holding_locks_lock);
for (auto const& lock_info : m_holding_locks_list) {
if (callback(lock_info) == IterationDecision::Break)
break;
}
}
template<VoidFunction<Thread::HoldingLockInfo const&> Callback>
inline void Thread::for_each_held_lock(Callback callback)
{
for_each_held_lock([&](auto const& lock_info) {
callback(lock_info);
return IterationDecision::Continue;
});
}
#endif
}
template<>