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

Niroj Pokhrel nirojpokhrel at gmail.com
Fri Jan 18 22:10:04 EST 2013


On Sat, Jan 19, 2013 at 8:13 AM, Peter Teoh <htmldeveloper at gmail.com> wrote:

>
>
> 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



Hi all,
Thank you very much. I have much idea now. However, I am still wondering
about these lines
" those resources that were shared across a fork() or vfork() were in
general *multiple references* to the same resource. " .
Is it that all the resources are shared as multiple references or if it is
otherwise. Will you please give me some example of the case which I should
not share the resources ? Thanking you all in advance.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20130119/849c8273/attachment-0001.html 


More information about the Kernelnewbies mailing list