I have a program with undefined behavior ( vfork() is used inappropriately ):
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
int main ( int argc, char *argv[] )
{
pid_t pid;
printf("___________befor fork______________.\n");
if((pid=vfork()) < 0)
perror("fork");
else if(pid > 0)
printf("parent\n");
else
printf("child\n");
printf("pid: %d, ppid: %d\n", getpid(), getppid());
//exit(0);
return 0;
}
If I use exit(0)
function instead return - output is:
___________befor fork______________.
child
pid: 4370, ppid: 4369
parent
pid: 4369, ppid: 2924
If I use return 0
- I get infinite output like this:
___________befor fork______________.
child
pid: 4455, ppid: 4454
parent
pid: 4454, ppid: 2924
___________befor fork______________.
child
pid: 4456, ppid: 4454
parent
pid: 4454, ppid: 2924
___________befor fork______________.
child
pid: 4457, ppid: 4454
parent
pid: 4454, ppid: 2924
and so on ...
I know that you can not use return
in the child after the vfork()
function.
But I don't understand why the parent does not end after return
call?
Thanks.
When a vfork system call is issued, the parent process will be suspended until the child process has either completed execution or been replaced with a new executable image via one of the "exec" family of system calls.
RETURN VALUE Upon successful completion, vfork() returns 0 to the child process and returns the process ID of the child process to the parent process. Otherwise, -1 is returned to the parent, no child process is created, and errno is set to indicate the error.
This is because both processes use the same address space, which contains the stack, stack pointer, and instruction pointer. vfork() acts as a special case of the clone() system call. It creates new processes without copying the address space of the parent process.
fork() and exit() I am the parent, the child is 16959. exit() closes all files and sockets, frees all memory and then terminates the process. The parameter of exit() is the only thing that survives and is handed over to the parent process.
It is not valid to return from the function in the child, because with vfork()
both the parent and child share the same stack and returning in the child will mess up the stack frame for the parent. Usually the call to main()
(in the start function) is followed by a call to exit()
or similar, so that call to exit()
in the child will overwrite the same stack space that the call to main()
was using (and is still using in the parent). So when the child does exit, the parent will return from vfork()
but the return address on the stack will likely be clobbered so it could return to any address or do anything at all.
Also, in the child, if you do not exec you should call _exit()
rather than exit()
. exit()
will flush the stdio output buffers but those same buffers are being managed by the parent, whereas _exit()
will just end the process.
By returning in your child process you are causing undefined behavior, so anything can really happen.
It looks like you parent process works fine, but the child process, instead of exiting, restarts main
function.
you can see the definition of vfork in the kernel.org : http://www.kernel.org/doc/man-pages/online/pages/man2/vfork.2.html . it is a good explanation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With