Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

difference between exit and return after vfork() call

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.

like image 432
nick Avatar asked Oct 06 '11 15:10

nick


People also ask

What happens when a running process execute a vfork () call?

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.

What does Vfork return?

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.

What is the difference between fork () vfork (() and clone ()?

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.

What does exit do in Fork?

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.


3 Answers

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.

like image 113
mark4o Avatar answered Sep 23 '22 15:09

mark4o


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.

like image 42
Piotr Praszmo Avatar answered Sep 21 '22 15:09

Piotr Praszmo


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.

like image 36
andy Avatar answered Sep 25 '22 15:09

andy