rCore-Tutorial-v3 icon indicating copy to clipboard operation
rCore-Tutorial-v3 copied to clipboard

ch5 TaskControlBlock::exec should initialize program_brk and heap_bottom

Open asd13902594299 opened this issue 7 months ago • 0 comments
trafficstars

在当前实现中, TaskControlBlock::exec 只有更新子进程的 inner.base_size = user_sp;, 并无更新 heap_bottomprogram_brk .

考虑一种情况, 如果我的父进程 f 使用了不少的 heap 空间, 这时候他现在尝试 fork+exec 弄一个子进程 s.

首先在 fork 的时候, 子进程完全复制了一份父进程的 heap 空间的内容(brk, heap_bottom, heap上的数据).

然后子进程调用 exec, 把他的 inner 的 memory_setfrom_elf() 的东西替换掉. 这时候原 memory_set, 即来自父进程的 heap 空间上的数据被释放了. 之后再把子进程自己 inner 中的 trap_cx_ppnbase_size 更新.

MemorySet::from_elf() 的实现可以看到, 他的 heap 空间已经是空的, 没有实际映射任何虚拟或者物理页.

pub fn from_elf(elf_data: &[u8]) -> (Self, usize, usize) {
    ...
    // map user stack with U flags
    memory_set.push(
        MapArea::new_with_va(
            user_stack_bottom.into(),
            user_stack_top.into(),
            MapType::Framed,
            MapPermission::R | MapPermission::W | MapPermission::U,
        ),
        None,
    );
    // used in sbrk
    memory_set.push(
        MapArea::new_with_va(
            user_stack_top.into(),
            user_stack_top.into(),
            MapType::Framed,
            MapPermission::R | MapPermission::W | MapPermission::U,
        ),
        None,
    );
    // map TrapContext
   ...
}

然而这时候子进程 inner 中的 brk, heap_bottom 依旧是使用的父进程的 brk 和 bottom. 但 memory_set 中现在并无对应的 heap 数据物理页. 此时若对这个子进程用 change_program_brk() 之类的函数, 会出现一些未定义行为.

因此我认为在 TaskControlBlock::exec() 中应该需要添加上:

...
// substitute memory_set
inner.memory_set = memory_set;
// update trap_cx ppn
inner.trap_cx_ppn = trap_cx_ppn;
// initialize base_size
inner.base_size = user_sp;
// initialize heap info
+ inner.heap_bottom = user_sp;
+ inner.program_brk = user_sp;
..

asd13902594299 avatar Apr 19 '25 07:04 asd13902594299