difference between exit and return after vfork() call

浪尽此生 提交于 2019-12-18 17:31:01

问题


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.


回答1:


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.




回答2:


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.




回答3:


The current POSIX standard does not support vfork() at all. In the old (1997-ish) POSIX standard, the page for vfork() said:

The vfork() function has the same effect as fork(), except that the behaviour 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() or one of the exec family of functions.

Your code is not calling either an exec family function or _exit(), so you invoke undefined behaviour, and anything that happens is legitimate.

You've just demonstrated why it is not usually sensible to use vfork(). IMNSHO, it is in the same camp as gets(); I know it exists but I would never use it voluntarily, and I'd be perfectly happy for the implementations to be:

pid_t vfork(void) { abort(); }
char *gets(char *buffer) { abort(); }



回答4:


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.



来源:https://stackoverflow.com/questions/7676619/difference-between-exit-and-return-after-vfork-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!