Thread (5 messages) 5 messages, 4 authors, 2013-01-19

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

From: Chinmay V S <hidden>
Date: 2013-01-19 02:15:32

Possibly related (same subject, not in this thread)

Completely agree with the flagpole analogy. In case of multiple references
to a shared resource, the system does not consider the resource free as
long as even one reference to it exists.

About the race-condition though i am not so sure. The parent process is
supposed to block on vfork() until the child process returns. This is a
crucial difference between vfork() and the more common fork().

http://linux.die.net/man/2/vfork
http://linux.die.net/man/2/fork

So in the above case i imagine the flow would be as follows:
1. Parent process starts execution.
2. vfork() called spawns child process.
3. Child process executes(parent blocked at vfork).
4. Child process completes and exits.
5. Parent process continues.
6. Parent process completes and exits.

The additonal references to resources(memory for example) are created in
step2 while spawning the child process. These references are deleted when
step4 completes. But the original references created by the parent process
in step1 still exist till end of step6 and hence resources will NOT be
freed in the middle.

I believe the race condition is entirely plausible if fork() is used
instead of vfork().

What interests me is the following line in the vfork manual page:
"...the behavior 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()..."

So the behaviour is undefined for modifying the variable "i"? Does this
mean that "i++" in the child process is NOT guaranteed to always reflect in
the parent process? (Though in either case there still wont be any
error/crash, just that the one outcome is not guaranteed across all
platforms/archs/implementations). Is it so? Any real-world experiences of
using vfork anyone?...

regards
CVS

On Sat, Jan 19, 2013 at 3:19 AM, [off-list ref] wrote:
On Fri, 18 Jan 2013 19:59:38 +0530, Niroj Pokhrel said:
quoted
I have been trying to create a process using vfork(). And both of the
child
quoted
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?
quoted
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
quoted
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.

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.
quoted
In the following code, however the process ran fine even though I have
exit(0) in the child process ........
quoted
#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.
quoted
        printf(" %d ",i++);
        exit(0);
    }
    else
    {
/* race condition here - may want wait() or waitpid() to synchronize? */
quoted
        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
quoted
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++.

(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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20130119/50fdbef0/attachment.html 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help