I thought the point of vfork is that they do not share an address space. But there are other things still shared and they should really just have a CreateProcess.
They still share an address space until exec replaces it for one of them. Particularly awful is that they share the same mutable stack which is a pathway that only leads to the inner circle of hell.
vfork() does the opposite of solving these problems. While there are a few functions that you can call after fork(), there is absolutely no function you can call after vfork() before exec(). You can't even write most local variables.
vfork() solves the problem of not wasting so much time on fork() when you're just going to call exec() afterwards (fork() does A LOT of work - potentially, anyway).
> vfork() does the opposite of solving these problems. While there are a few functions that you can call after fork(), there is absolutely no function you can call after vfork() before exec(). You can't even write most local variables.
Mostly wrong.
You can call functions on the child side of vfork(), but you don't want to exec() in them -- you want to exec() in the same function that called vfork().
And you can write to local variables, but you have to be careful about it.
There's a ton of vfork()-using code that does these things.
Now, it's true that a compiler optimizer that knows nothing about vfork() but knows about _exit()'s semantics, could delete code it thinks is unreachable. So there is some issue, but you can just disable the optimizer if you run into this.
That's all undefined behavior, under POSIX at least [0]:
> The vfork() function has the same effect as
fork(2), except that the behavior is undefined if the process
created by vfork() either modifies any data other than a variable
of type pid_t used to store the return value from vfork(), or
returns from the function in which vfork() was called, or calls
any other function before successfully calling _exit(2) or one of
the exec(3) family of functions.
So sure - you can do these things, but they have very little defined semantics after vfork().
It is true that Linux describes the semantics more clearly, so perhaps on Linux it is safer to use.
Isn't vfork much worse in terms of the problem the author is talking about, since the child can now acquire locks in the _parent's_ address space?
I thought the point of vfork is that they do not share an address space. But there are other things still shared and they should really just have a CreateProcess.
no, fork creates a new address space, vfork doesn't
the posix_spawn mentioned in the article is effectively the equivalent of CreateProcess
4 replies →
They still share an address space until exec replaces it for one of them. Particularly awful is that they share the same mutable stack which is a pathway that only leads to the inner circle of hell.
2 replies →
vfork() does the opposite of solving these problems. While there are a few functions that you can call after fork(), there is absolutely no function you can call after vfork() before exec(). You can't even write most local variables.
vfork() solves the problem of not wasting so much time on fork() when you're just going to call exec() afterwards (fork() does A LOT of work - potentially, anyway).
> vfork() does the opposite of solving these problems. While there are a few functions that you can call after fork(), there is absolutely no function you can call after vfork() before exec(). You can't even write most local variables.
Mostly wrong.
You can call functions on the child side of vfork(), but you don't want to exec() in them -- you want to exec() in the same function that called vfork().
And you can write to local variables, but you have to be careful about it.
There's a ton of vfork()-using code that does these things.
Now, it's true that a compiler optimizer that knows nothing about vfork() but knows about _exit()'s semantics, could delete code it thinks is unreachable. So there is some issue, but you can just disable the optimizer if you run into this.
That's all undefined behavior, under POSIX at least [0]:
> The vfork() function has the same effect as fork(2), except that the behavior is undefined if the process created by vfork() either modifies any data other than a variable of type pid_t used to store the return value from vfork(), or returns from the function in which vfork() was called, or calls any other function before successfully calling _exit(2) or one of the exec(3) family of functions.
So sure - you can do these things, but they have very little defined semantics after vfork().
It is true that Linux describes the semantics more clearly, so perhaps on Linux it is safer to use.
[0] https://man7.org/linux/man-pages/man2/vfork.2.html
4 replies →