Why doesn't address change in forked process? Why doesn't address change in forked process? linux linux

Why doesn't address change in forked process?


My expectation was that when I change a variable in the child, this should cause that variable to get a new address.

No, because they are virtual addresses.

If I understand correctly, Linux does copy-on-write with fork. So I would expect the variable address in the parent and child to match until I change it in one of them.

A new physical page will be used somewhere, but the virtual address can (and will) stay the same.

Is this because with copy-on-write a new page is allocated from physical memory, but the process address space is unchanged - just remapped to the new page by the TLB?

Of course. Otherwise it would be way less useful. If it worked as you say, then consider any pointer you had previous to the fork would become invalid suddenly. Think about code as simple as:

int * p = new int;if (!fork()) {    // the child    *p = 42;    // now `p` is invalid since we wrote to it?!    // another read or write would segfault!    *p = 43;}

In a way, it would be like having a live program on one of those games where the platforms (pages for us) fall down when you step on them once. Quite fun! :)

We could examine fixing the problem by having the operating system or the CPU rewrite (somehow) your pointers with the new address when that happens to keep everything working.

However, even if that were possible, we have more issues. For instance, you need to take care of allocations that cover several pages. Imagine the stack (assuming Linux does CoW for the stack too on fork()). As soon as you wrote anything to the stack you would have to update the stack pointer and copy all the pages, not just the modified one.

Then we have to solve indirect pointers and pointers in data structures that do not point to allocations, etc. It seems impossible to solve without tracking which registers and pointers need to be updated for each possible future write (or having some different implementation for C pointers overall as @R mentions -- same for registers etc.).