Reap zombie children when exit

This can fix memory leakage when parent not wait4 children.
This commit is contained in:
Hui, Chunyang 2021-08-05 06:03:44 +00:00 committed by Zongmin.Gu
parent 865e38258b
commit 80a27bc0f9
4 changed files with 36 additions and 1 deletions

@ -7,6 +7,7 @@ use super::*;
use crate::exception::*;
use crate::fs::HostStdioFds;
use crate::interrupt;
use crate::process::idle_reap_zombie_children;
use crate::process::ProcessFilter;
use crate::signal::SigNum;
use crate::time::up_time::init;
@ -284,6 +285,9 @@ fn do_new_process(
fn do_exec_thread(libos_tid: pid_t, host_tid: pid_t) -> Result<i32> {
let status = process::task::exec(libos_tid, host_tid)?;
// Idle process should reap all zombie children
idle_reap_zombie_children()?;
// sync file system
// TODO: only sync when all processes exit
use rcore_fs::vfs::FileSystem;

@ -3,6 +3,36 @@ use super::wait::Waiter;
use super::{table, ProcessRef, ProcessStatus};
use crate::prelude::*;
// Children process exits without parent calls wait4 should be reaped by Idle process in the end.
// Without this, there might be memory leakage when exit.
pub fn idle_reap_zombie_children() -> Result<()> {
let idle_ref = super::IDLE.process().clone();
let mut zombie_pids = Vec::new();
loop {
// This needs to acquire lock every time.
let mut idle_inner = idle_ref.inner();
let children = idle_inner.children().unwrap();
match children
.iter()
.find(|child| child.status() == ProcessStatus::Zombie)
{
Some(zombie_child) => {
// Reap one zombie each time.
let zombie_pid = zombie_child.pid();
let exit_status = free_zombie_child(idle_inner, zombie_pid);
zombie_pids.push(zombie_pid);
}
None => {
// None zombie child, just return
break;
}
}
}
info!("Idle process reaps zombie children pid = {:?}", zombie_pids);
return Ok(());
}
pub fn do_wait4(child_filter: &ProcessFilter, options: WaitOptions) -> Result<(pid_t, i32)> {
// Lock the process early to ensure that we do not miss any changes in
// children processes

@ -24,6 +24,7 @@ pub use self::do_exit::handle_force_exit;
pub use self::do_futex::{futex_wait, futex_wake};
pub use self::do_robust_list::RobustListHead;
pub use self::do_spawn::do_spawn_without_exec;
pub use self::do_wait4::idle_reap_zombie_children;
pub use self::process::{Process, ProcessFilter, ProcessStatus, IDLE};
pub use self::spawn_attribute::posix_spawnattr_t;
pub use self::syscalls::*;

@ -121,7 +121,7 @@ impl Drop for UserSpaceVMRange {
}
USER_SPACE_VM_MANAGER.add_free_size(self);
info!("user space vm free: {:?}", self.vm_range);
assert!(unsafe { sgx_free_rsrv_mem(addr, size) == 0 });
}
}