After fork, parent and child run the same code from the same instruction. How does
fork() come to return 0 in the child but the child’s pid in the parent?
Test yourself · category 8 of 20
fork, exec, exit, wait, kill
How a process is born as a copy, becomes a new program, dies in two halves as a zombie, is reaped by its parent, and is killed by a flag it checks itself.
True or false: a fork child’s kernel stack starts out as a copy of its parent’s kernel
stack, so that the child can return through sys_fork, syscall and usertrap just
like the parent.
Why?
A child process has called exit and is now a ZOMBIE; its parent has not called
wait yet. Which of these does the zombie still hold?
ls (on hart 2) calls exit(0) while its parent, the shell, sleeps in kwait. Put
these events in the order they must happen.
- Hart 2’s scheduler releases
ls’sp->lock kexitcallswakeup(p->parent)kexitclosesls’s open files and drops its current directorykexitreleaseswait_lockand callssched- The shell’s
kwaitacquiresls’sp->lock, seesZOMBIEand callsfreeproc kexitacquires its ownp->lockand setsstate = ZOMBIEkexitacquireswait_lockand callsreparent
Process A is running in user mode on hart 1. On hart 0, another process calls
kill(A's pid), and kkill finds A’s slot. What does kkill do to A?
True or false: after a successful exec, the process still has the same pid and the
same open file descriptors it had before.
Why?
After loading the program’s segments, kexec calls uvmalloc on line 91. How many
pages does that call map in the new page table?
In kfork, click the line at which the child first becomes eligible to be run by a
scheduler on any hart.
Your pick: none yet (click a line in the code)
Near its end, kfork releases the child’s lock (line 294), takes wait_lock to set
np->parent, releases it, and only then re-acquires the child’s lock. Why not keep the
child’s lock and take wait_lock inside it?
Line 279 copies the parent’s whole trapframe into the child’s. What is in the child’s
trapframe->kernel_sp right after that line, and why is it not a problem?
In kexit, wakeup(p->parent) (line 353) comes before acquire(&p->lock) (line
355). Why can’t kexit take its own lock first?
kwait holds wait_lock from its scan until after sleep_prepare, and releases it
only just before sleep. Why does it register before releasing wait_lock?
A process whose user memory is exactly 5 pages, all present, at virtual addresses
0x0–0x4fff, calls fork, and it succeeds. How many pages does the whole kfork
take from kalloc (directly or through the functions it calls)?
allocproc claims proc[4]. What value does line 147 store in p->context.sp?
Use KSTACK(p) = TRAMPOLINE - ((p) + 1) * 2 * PGSIZE, TRAMPOLINE = MAXVA - PGSIZE,
MAXVA = 1 << 38 and PGSIZE = 4096. Answer in hex.
Process P is asleep in piperead on an empty pipe whose write end is still open
(it slept at line 126). Another process calls kill(P). The pipe stays empty. What
happens to P?
Some sleep loops check killed each time round, so that a killed process does not
wait forever. Which of these do?
Click the line at which the process’s user address space becomes the new program’s,
the commit point of kexec.
Your pick: none yet (click a line in the code)
Match each process state with the code that sets it in the situation described.
ls called exit(0) (a system call). Its kexit has just executed line 358,
p->state = ZOMBIE. What is the state of the hart running it?
True or false: as soon as a process’s state is ZOMBIE, no hart is executing on its
kernel stack any more.
Why?
Process A is spinning in user mode on hart 1, making no system calls. On hart 0, another
process calls kill(A's pid), and it returns 0. Which of these are true?
kexec's argument loop writes ustack[argc] with no check that argc < MAXARG
(ustack has MAXARG = 32 entries, on the kernel stack). What stops a user program
from overflowing ustack by calling exec with 40 arguments?
Process P in piperead has passed the killed check on line 120 and called
sleep_prepare on line 124, but has not yet called sleep(). On another hart, kill(P)
runs to completion. Then the pipe’s writer does nothing for an hour, keeping its end open.
What happens to P during that hour?
True or false: because first in forkret is a plain static int, read and cleared
with no lock and no atomic instruction, two harts could both run the if (first) block
and both call fsinit.
Why?
Process P (a child of the shell) has a child Z that has already exited and is a
ZOMBIE; P never called wait. Now P itself calls exit. Who eventually calls
freeproc on Z?