1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 01:27:43 +00:00

Kernel: Make sure threads which don't do any syscalls are terminated

Steps to reproduce:

$ cat loop.c
int main() { for (;;); }
$ gcc -o loop loop.c
$ ./loop

Terminating this process wasn't previously possible because we only
checked whether the thread should be terminated on syscall exit.
This commit is contained in:
Gunnar Beutner 2021-06-19 11:27:20 +02:00 committed by Andreas Kling
parent c980a51776
commit 3c3a1726df
3 changed files with 20 additions and 0 deletions

View file

@ -192,6 +192,13 @@ bool Scheduler::pick_next()
ScopedSpinLock lock(g_scheduler_lock); ScopedSpinLock lock(g_scheduler_lock);
auto current_thread = Thread::current();
if (current_thread->should_die() && current_thread->may_die_immediately()) {
// Ordinarily the thread would die on syscall exit, however if the thread
// doesn't perform any syscalls we still need to mark it for termination here.
current_thread->set_state(Thread::Dying);
}
if constexpr (SCHEDULER_RUNNABLE_DEBUG) { if constexpr (SCHEDULER_RUNNABLE_DEBUG) {
dump_thread_list(); dump_thread_list();
} }

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <AK/ScopeGuard.h>
#include <Kernel/API/Syscall.h> #include <Kernel/API/Syscall.h>
#include <Kernel/Arch/x86/CPU.h> #include <Kernel/Arch/x86/CPU.h>
#include <Kernel/Panic.h> #include <Kernel/Panic.h>
@ -129,6 +130,14 @@ NEVER_INLINE void syscall_handler(TrapFrame* trap)
{ {
auto& regs = *trap->regs; auto& regs = *trap->regs;
auto current_thread = Thread::current(); auto current_thread = Thread::current();
{
ScopedSpinLock lock(g_scheduler_lock);
current_thread->set_may_die_immediately(false);
}
ScopeGuard reset_may_die_immediately = [&current_thread] {
ScopedSpinLock lock(g_scheduler_lock);
current_thread->set_may_die_immediately(true);
};
VERIFY(current_thread->previous_mode() == Thread::PreviousMode::UserMode); VERIFY(current_thread->previous_mode() == Thread::PreviousMode::UserMode);
auto& process = current_thread->process(); auto& process = current_thread->process();

View file

@ -1134,6 +1134,9 @@ public:
bool is_profiling_suppressed() const { return m_is_profiling_suppressed; } bool is_profiling_suppressed() const { return m_is_profiling_suppressed; }
void set_profiling_suppressed() { m_is_profiling_suppressed = true; } void set_profiling_suppressed() { m_is_profiling_suppressed = true; }
bool may_die_immediately() const { return m_may_die_immediately; }
void set_may_die_immediately(bool flag) { m_may_die_immediately = flag; }
private: private:
Thread(NonnullRefPtr<Process>, NonnullOwnPtr<Region>, NonnullRefPtr<Timer>); Thread(NonnullRefPtr<Process>, NonnullOwnPtr<Region>, NonnullRefPtr<Timer>);
@ -1227,6 +1230,7 @@ private:
Optional<Range> m_thread_specific_range; Optional<Range> m_thread_specific_range;
Array<SignalActionData, NSIG> m_signal_action_data; Array<SignalActionData, NSIG> m_signal_action_data;
Blocker* m_blocker { nullptr }; Blocker* m_blocker { nullptr };
bool m_may_die_immediately { true };
#if LOCK_DEBUG #if LOCK_DEBUG
struct HoldingLockInfo { struct HoldingLockInfo {