mirror of
https://github.com/MeiK2333/river.git
synced 2025-11-04 14:49:40 +08:00
修复一处内存泄漏问题
This commit is contained in:
parent
ffb6a69f3f
commit
19489557d3
@ -7,7 +7,5 @@
|
|||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- 解决偶发性的 `wait4 failure` 问题
|
- 解决偶发性的 `wait4 failure` 问题
|
||||||
- 解决偶发性的内存测量不精确问题
|
|
||||||
- 解决内存占用已经超出限制时,未能结束进程,从而结果表现为 TLE 的问题
|
- 解决内存占用已经超出限制时,未能结束进程,从而结果表现为 TLE 的问题
|
||||||
- 修复 Rust 无法编译的问题
|
- 修复 Rust 无法编译的问题
|
||||||
- 修复貌似内存泄漏的问题
|
|
||||||
|
|||||||
@ -13,6 +13,7 @@ RUN apt-get install -y software-properties-common && add-apt-repository -y ppa:d
|
|||||||
# install rust
|
# install rust
|
||||||
RUN apt-get install -y curl && curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain stable -y
|
RUN apt-get install -y curl && curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain stable -y
|
||||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||||
|
RUN rustup default stable
|
||||||
|
|
||||||
# install node
|
# install node
|
||||||
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - && apt-get install -y nodejs
|
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - && apt-get install -y nodejs
|
||||||
@ -35,5 +36,3 @@ RUN add-apt-repository -y ppa:longsleep/golang-backports && apt-get install -y g
|
|||||||
RUN apt-get install -y default-jdk
|
RUN apt-get install -y default-jdk
|
||||||
|
|
||||||
RUN rm -rf /var/lib/apt/lists/*
|
RUN rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
RUN rustup default stable
|
|
||||||
@ -70,22 +70,45 @@ impl Process {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 为 clone 的栈所需的指针创建 Send 与 Sync 包装
|
||||||
|
// 因为 Rust 编译器不允许原始的 c_void 在线程间同步
|
||||||
|
// 我们可以创建一个包装来规避这个问题,但前提是我们需要明白我们在做什么
|
||||||
|
struct Stack {
|
||||||
|
stack: *const libc::c_void,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for Stack {}
|
||||||
|
unsafe impl Sync for Stack {}
|
||||||
|
|
||||||
pub struct Runner {
|
pub struct Runner {
|
||||||
process: Process,
|
process: Process,
|
||||||
pid: i32,
|
pid: i32,
|
||||||
tx: Arc<Mutex<mpsc::Sender<RunnerStatus>>>,
|
tx: Arc<Mutex<mpsc::Sender<RunnerStatus>>>,
|
||||||
rx: Arc<Mutex<mpsc::Receiver<RunnerStatus>>>,
|
rx: Arc<Mutex<mpsc::Receiver<RunnerStatus>>>,
|
||||||
|
stack: Stack,
|
||||||
cgroup_set: CGroupSet,
|
cgroup_set: CGroupSet,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Runner {
|
impl Runner {
|
||||||
pub fn from(process: Process) -> Result<Runner> {
|
pub fn from(process: Process) -> Result<Runner> {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
|
let stack = unsafe {
|
||||||
|
libc::mmap(
|
||||||
|
ptr::null_mut(),
|
||||||
|
STACK_SIZE,
|
||||||
|
libc::PROT_READ | libc::PROT_WRITE,
|
||||||
|
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS | libc::MAP_STACK,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
debug!("mmap stack");
|
||||||
Ok(Runner {
|
Ok(Runner {
|
||||||
process: process,
|
process: process,
|
||||||
pid: -1,
|
pid: -1,
|
||||||
tx: Arc::new(Mutex::new(tx)),
|
tx: Arc::new(Mutex::new(tx)),
|
||||||
rx: Arc::new(Mutex::new(rx)),
|
rx: Arc::new(Mutex::new(rx)),
|
||||||
|
stack: Stack { stack: stack },
|
||||||
cgroup_set: CGroupSet::new()?,
|
cgroup_set: CGroupSet::new()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -107,6 +130,8 @@ impl Drop for Runner {
|
|||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
debug!("dropping");
|
debug!("dropping");
|
||||||
unsafe {
|
unsafe {
|
||||||
|
libc::munmap(self.stack.stack as *mut libc::c_void, STACK_SIZE);
|
||||||
|
debug!("munmap stack");
|
||||||
killpid(self.pid);
|
killpid(self.pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,24 +143,13 @@ impl Future for Runner {
|
|||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<RunnerStatus>> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<RunnerStatus>> {
|
||||||
let runner = Pin::into_inner(self);
|
let runner = Pin::into_inner(self);
|
||||||
let time_limit = (runner.process.time_limit / 1000 + 1) as u64 * 2;
|
let time_limit = (runner.process.time_limit / 1000 + 1) as u64 * 2;
|
||||||
// 创建 clone 所需的栈空间
|
|
||||||
let stack = unsafe {
|
|
||||||
libc::mmap(
|
|
||||||
ptr::null_mut(),
|
|
||||||
STACK_SIZE,
|
|
||||||
libc::PROT_READ | libc::PROT_WRITE,
|
|
||||||
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS | libc::MAP_STACK,
|
|
||||||
-1,
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
// 如果 pid == -1,则说明子进程还没有运行
|
// 如果 pid == -1,则说明子进程还没有运行
|
||||||
if runner.pid == -1 {
|
if runner.pid == -1 {
|
||||||
let waker = cx.waker().clone();
|
let waker = cx.waker().clone();
|
||||||
let pid = unsafe {
|
let pid = unsafe {
|
||||||
libc::clone(
|
libc::clone(
|
||||||
runit,
|
runit,
|
||||||
(stack as usize + STACK_SIZE) as *mut libc::c_void,
|
(runner.stack.stack as usize + STACK_SIZE) as *mut libc::c_void,
|
||||||
libc::SIGCHLD
|
libc::SIGCHLD
|
||||||
| libc::CLONE_NEWUTS // 设置新的 UTS 名称空间(主机名、网络名等)
|
| libc::CLONE_NEWUTS // 设置新的 UTS 名称空间(主机名、网络名等)
|
||||||
| libc::CLONE_NEWNET // 设置新的网络空间,如果没有配置网络,则该沙盒内部将无法联网
|
| libc::CLONE_NEWNET // 设置新的网络空间,如果没有配置网络,则该沙盒内部将无法联网
|
||||||
@ -175,9 +189,6 @@ impl Future for Runner {
|
|||||||
});
|
});
|
||||||
return Poll::Pending;
|
return Poll::Pending;
|
||||||
} else {
|
} else {
|
||||||
unsafe {
|
|
||||||
libc::munmap(stack, STACK_SIZE);
|
|
||||||
}
|
|
||||||
let mut status = runner.rx.lock().unwrap().recv().unwrap();
|
let mut status = runner.rx.lock().unwrap().recv().unwrap();
|
||||||
let mem_used = match runner
|
let mem_used = match runner
|
||||||
.cgroup_set
|
.cgroup_set
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user