From 53a46824182b176a323e76ad1381ed17960f1712 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Sun, 6 Sep 2020 15:01:24 -0700 Subject: [PATCH] [kernel] Fix current thread deletion bug Defer from calling process::thread_exited() in scheduler::prune() if the thread in question is the currently-executing thread, so that we don't blow away the stack we're executing on. The next call to prune will pick up the exited thread. --- src/kernel/frame_allocator.cpp | 2 ++ src/kernel/scheduler.cpp | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/kernel/frame_allocator.cpp b/src/kernel/frame_allocator.cpp index bee3d72..0a91ec0 100644 --- a/src/kernel/frame_allocator.cpp +++ b/src/kernel/frame_allocator.cpp @@ -45,6 +45,8 @@ inline uintptr_t end(frame_block *node) { return node->address + node->count * f void frame_allocator::free(uintptr_t address, size_t count) { + kassert(address % frame_size == 0, "Trying to free a non page-aligned frame!"); + frame_block_node *node = reinterpret_cast(address + page_offset); diff --git a/src/kernel/scheduler.cpp b/src/kernel/scheduler.cpp index c24a22a..4cd7196 100644 --- a/src/kernel/scheduler.cpp +++ b/src/kernel/scheduler.cpp @@ -241,6 +241,7 @@ void scheduler::prune(uint64_t now) bool ready = th->has_state(thread::state::ready); bool exited = th->has_state(thread::state::exited); bool constant = th->has_state(thread::state::constant); + bool current = tcb == m_current; ready |= th->wake_on_time(now); @@ -253,7 +254,10 @@ void scheduler::prune(uint64_t now) if (exited) { process &p = th->parent(); - if(p.thread_exited(th)) + + // If the current thread has exited, wait until the next call + // to prune() to delete it. + if(!current && p.thread_exited(th)) delete &p; } else { log::debug(logs::task, "Prune: readying unblocked thread %llx", th->koid());