no error thrown with exit(0) in the child process of vfork()

Peter Teoh htmldeveloper at gmail.com
Fri Jan 18 21:43:15 EST 2013


On Sat, Jan 19, 2013 at 5:49 AM, <Valdis.Kletnieks at vt.edu> wrote:

> On Fri, 18 Jan 2013 19:59:38 +0530, Niroj Pokhrel said:
>
> > I have been trying to create a process using vfork(). And both of the
> child
> > and the parent process execute it in the same address space. So, if I
> > execute exit(0) in the child process, it should throw some error right.
>
> Why do you think it should throw an error?
>
> > Since the execution is happening in child process first and if I release
> > all the resources by using exit(0) in the child process then parent
> should
> > be deprived of the resources and should throw some errors right ??
>
> No, because those resources that were shared across a fork() or vfork()
> were in
> general *multiple references* to the same resource.
>
>
Yes, correct, Valdis is right.   Normally, when u free resources (which is
what "exit()" will do), u must also remember to check something call
"reference count".

Basic malloc() and free() memory management internal data structure also
comes with other info like size (which is 4 bytes BEHIND the first byte
where the pointer points to, and other info).   More info:

http://stackoverflow.com/questions/1957099/how-do-free-and-malloc-work-in-c

but what is lacking is reference counting.   But this feature is available
in Java and C++ libraries for memory allocation.

Concept discussed here:

http://stoneship.org/essays/c-reference-counting-and-you/

Interesting....


> As an example - imagine a flagpole.  You grab it with your hand, you're
> now holding it.  You invite your friend to come over and grab it with
> his hand - now he's holding it too.
>
> But either one of you can let go of the flagpole - and the other one is
> still holding the flagpole until *they* let go.  And the order you let
> go doesn't matter in this case - which is important because your example
> code has a race condition....
>
> Note that there are other cases where the order people let go *does*
> matter.
> This is when you start having to worry about "locking order" and things
> like
> that.
>
> > In the following code, however the process ran fine even though I have
> > exit(0) in the child process ........
>
> > #include<stdio.h>
> > #include<stdlib.h>
> > #include<sys/types.h>
> > #include<unistd.h>
> > int main()
> > {
> >     int val,i=0;
> >     val=vfork();
> >     if(val==0)
> >     {
> >         printf("\nI am a child process.\n");
>
> Note that printf() gets interesting due to stdio buffering.  You probably
> want to call setbuf() and guarantee line-buffering of the output if you're
> playing these sorts of games - the buffering can totally mask a real race
> condition or other bug.
>
> >         printf(" %d ",i++);
> >         exit(0);
> >     }
> >     else
> >     {
>
> /* race condition here - may want wait() or waitpid() to synchronize? */
>
> >         printf("\nI am a parent process.\n");
> >         printf(" %d ",i);
> >     }
> >     return 0;
> > }
> > // The program is running fine .....
> > But as I have read it should throw some error right ?? I don't know what
> I
> > am missing . Please point out the point I'm missing. Thanking you in
> > advance.
>
> You're also missing the fact that after the vfork(), there's no real
> guarantee of which will run first - which means that the parent can race
> and output the 'printf("%d",i)" *before* the child process gets a chance
> to do the i++.
>
>
I don't think there is any issue here (racing, or child calling exit before
parent called exit()).   Read the man-page:

       vfork()  differs from fork(2) in that the parent is suspended until
the
       child terminates (either normally, by calling _exit(2), or
 abnormally,
       after  delivery  of  a  fatal signal), or it makes a call to
execve(2).
       Until that point, the child shares all memory with its parent,
 includ‐
       ing  the stack.  The child must not return from the current function
or
       call exit(3), but may call _exit(2).


So:

1.   if parent is suspended, it also means no contention issue, child can
use the "i++", which is single-copy in memory, and parent is not even
touching it.

2.   It is clearly documented above - the vfork()'s child CAN exit() before
the parent calling exit().

3.   More important is to understand the the use of vfork() - u don't to
create a duplicate memory page table because u want to call execve()
immediately, which will overwrite everything in memory with the new binary
inside execve() command.

Hope I got it right?


> (Aside - for a while, there was a patch in place that ensured that the
> child would run first, on the theory that the child would often do
> something
> short that the parent was waiting on, so scheduling parent-first would just
> result in the parent running, blocking to wait, and we end up running the
> child anyhow before the parent could continue.  It broke an *amazing*
> amount
> of stuff in userspace because often the child would exit() before the
> parent was
> ready to deal with the child process's termination. Usual failure mode was
> the parent would set a SIGCHLD handler, and wait for the signal which never
> happened because the SIGCHLD actually fired *before* the handler was set
> up).
>
> (And on non-cache-coherent systems, it's even possible that the i++ happens
> on a different CPU first, and the CPU running the parent process never
> becomes
> aware of it.  See 'Documentation/memory-barriers.txt' in the Linux source
> for more info on how this works for data inside the kernel.  This example
> is out in userspace, so other techniques are required instead to do
> cross-CPU
> synchronization.
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>
>


-- 
Regards,
Peter Teoh
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20130119/191fd00a/attachment-0001.html 


More information about the Kernelnewbies mailing list