in vfork child are created repeatedly

206 views Asked by At

Anyone can explain the following code:

#include<stdio.h>
#include<stdlib.h>
main()
{
  int a=1;
  int pid;
  if((pid = vfork()) == 0)
  {
    printf("This is child . %d\n", getpid() );
    a=2;
  }
  else 
  {
    printf("%d\t%d\n",getpid(),a);
    sleep(1);
  }
}

In the above code, child processes are created repeatedly. Can anyone please help me understand the logic?

2

There are 2 answers

3
Art On BEST ANSWER

Read the manual page for vfork. Especially the part where it tells you what you are allowed to do in the child. You are not allowed to call getpid in the child. You are not allowed to call printf in the child. You are not allowed to set the variable a. You are not allowed to return from the function that called vfork in the child. You did all those things therefore the code does something unexpected. Unfortunately for you the unexpected thing isn't crashing.

You may only call _exit or one of the exec* functions in a vfork:ed child. Nothing else.

The vfork system call is a optimization hack from the days when fork was very expensive. So what it does it to suspend the parent process and use the parents address space in the child (this may or may not be true depending on operating system) until the child calls exec* or _exit. Any memory write that the child does will overwrite memory in the parent process. Calling functions will overwrite memory in ways that the parent process doesn't expect. Returning from the function that called vfork will definitely overwrite state that the parent expects to be intact (like the return addresses and saved stack pointers). Calling printf will overwrite stdio buffers that the parent doesn't expect to be overwritten, etc.

It could probably be reasoned why in your case the parent calls itself again after the child exits, after all computers are quite deterministic. If you analyze the crt code that calls main, the various atexit handlers in libc and other cleanup you could probably figure out exactly what happens to write what at the right place on the stack that makes the parent confused and return to the wrong place after the syscall returns. Disassemble the code and go for it. Or you could just search this site for the dozens of other questions about vfork and notice that they all follow the same theme: "Why does vfork do something unexpected when I do something the documentation tells me not to do?". It does it because it's undefined behavior and the way undefined behavior behaves is undefined. In your case overwriting memory that the parent didn't expect to have overwritten happened to make the parent call itself again. In other cases I've seen it made printf print twice. In other cases nothing bad happened. In other cases the program crashed.

4
Esakki Thangam On

You should terminate the child process using the exit() or exec. otherwise the child termination status will not reach to the parent. so, the child process is in zombie state.