mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 20:07:36 +00:00
Kernel: Stop leaking first thread on errors in sys$fork
Until the thread is first set as Runnable at the end of sys$fork, its state is Invalid, and as a result, the Finalizer which is searching for Dying threads will never find it if the syscall short-circuits due to an error condition like OOM. This also meant the parent Process of the thread would be leaked as well.
This commit is contained in:
parent
6901d3dcec
commit
c1fe844da4
1 changed files with 11 additions and 0 deletions
|
@ -18,6 +18,15 @@ ErrorOr<FlatPtr> Process::sys$fork(RegisterState& regs)
|
||||||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||||
TRY(require_promise(Pledge::proc));
|
TRY(require_promise(Pledge::proc));
|
||||||
RefPtr<Thread> child_first_thread;
|
RefPtr<Thread> child_first_thread;
|
||||||
|
|
||||||
|
ArmedScopeGuard thread_finalizer_guard = [&child_first_thread]() {
|
||||||
|
SpinlockLocker lock(g_scheduler_lock);
|
||||||
|
if (child_first_thread) {
|
||||||
|
child_first_thread->detach();
|
||||||
|
child_first_thread->set_state(Thread::State::Dying);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
auto child_name = TRY(m_name->try_clone());
|
auto child_name = TRY(m_name->try_clone());
|
||||||
auto child = TRY(Process::try_create(child_first_thread, move(child_name), uid(), gid(), pid(), m_is_kernel_process, current_directory(), m_executable, m_tty, this));
|
auto child = TRY(Process::try_create(child_first_thread, move(child_name), uid(), gid(), pid(), m_is_kernel_process, current_directory(), m_executable, m_tty, this));
|
||||||
TRY(m_unveil_data.with([&](auto& parent_unveil_data) -> ErrorOr<void> {
|
TRY(m_unveil_data.with([&](auto& parent_unveil_data) -> ErrorOr<void> {
|
||||||
|
@ -120,6 +129,8 @@ ErrorOr<FlatPtr> Process::sys$fork(RegisterState& regs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thread_finalizer_guard.disarm();
|
||||||
|
|
||||||
Process::register_new(*child);
|
Process::register_new(*child);
|
||||||
|
|
||||||
PerformanceManager::add_process_created_event(*child);
|
PerformanceManager::add_process_created_event(*child);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue