- 
                Notifications
    
You must be signed in to change notification settings  - Fork 535
 
Open
Description
在当前实现中, TaskControlBlock::exec 只有更新子进程的 inner.base_size = user_sp;, 并无更新 heap_bottom 和 program_brk .
考虑一种情况, 如果我的父进程 f 使用了不少的 heap 空间, 这时候他现在尝试 fork+exec 弄一个子进程 s.
首先在 fork 的时候, 子进程完全复制了一份父进程的 heap 空间的内容(brk, heap_bottom, heap上的数据).
然后子进程调用 exec, 把他的 inner 的 memory_set 用 from_elf() 的东西替换掉. 这时候原 memory_set, 即来自父进程的 heap 空间上的数据被释放了. 之后再把子进程自己 inner 中的 trap_cx_ppn 和 base_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;
..Metadata
Metadata
Assignees
Labels
No labels