clinuxforkcpu-registers

Does Linux fork even copy registers?


I recently learned that fork applies COW (copy on write) even on registers.

I played with a simple toy case to verify:

(gdb) info inferiors
  Num  Description       Connection           Executable
* 1    process 59316     1 (native)           /home/Drew/mycode/a.out
  2    process 59386     1 (native)           /home/Drew/mycode/a.out
(gdb) print( $rdi )
$1 = 18874385
(gdb) set $rdi=42
(gdb) print( $rdi )
$2 = 42
(gdb) inferior 2
[Switching to inferior 2 [process 59386] (/home/Drew/mycode/a.out)]
[Switching to thread 2.1 (process 59386)]
#0  0x00002aaaab090291 in fork () from /lib64/libc.so.6
(gdb) print( $rdi )
$3 = 18874385

As you guys see, modifying rdi in parent proc does not interfere child proc.

I wonder how is it done? does modern CPU provides multiple same registers exclusively for multi-process?

EDIT:

Thanks to you fellows for commenting. I'll answer the questions in comments here collectively, hope it helps clarify.

The reference I'm using is this lecture note.

I generally want to figure out:


Solution

  • Systems that provide pre-emptive multi-tasking provide CPU virtualization. This allows each thread to behave as if it has a CPU core (and its registers) to itself. More specifically, this allows a thread to use registers without having to worry about them getting changed by another thread (of the same process or a different one) in the middle of an operation.

    This is the case no matter how the thread is created, and thus includes threads created by fork. How the system achieves this is not relevant. But it ensures that any changes to, say, rdi or the instruction pointer in one thread isn't seen in another.

    I don't know what guarantees fork provides about the initial value of registers after a fork. It could be the same guarantees as other calls covered by the system's ABI.