Mailing List Archive

vfork specs
Implementing the vfork syscall wrapper in the libc apparently provides
some problems. To find a solution it's necessary to get a
specification of vfork, or at least make one up for Linux.
The problem is this: the vfork'ed process using the same VM as the
initial process. Assume the following code for now:
void
bar ()
{
if ((pid = vfork ()) == 0)
foo (0);
else if (pid == -1)
...error...
When calling the vfork wrapper we have the following stack layout:
...something...
return address bar after vfork call
Now the child returns from the vfork call and calls `foo' with the
resulting layout:
...something...
0
return address bar after foo call
May `foo' then exit and so the parent process starts and it sees the
return address 0 (zero) which was pushed as a parameter for `foo'.
This certainly is a situation we have to deal with and make sure that
the return address from the `vfork' syscall stays valid. But this is
only have of the story. It gets complicated if the use of the vfork
is not restricted. Assume this:
void
bar ()
{
pid_t p = baz ();
if (p == 0)
foo (0);
}
pid_t
baz ()
{
return vfork ();
}
Now the stack layout when reachine the syscall wrapper is
...something...
return address bar after baz call
return address baz after vfork call
At the time the function foo is called the stack layout is
...something...
0
return address bar after foo call
I.e., we are again f*cked. This can of course be repeated for
arbitrary depths of function calls.
So the question is: does the vfork interface on other platforms
restricts the use of vfork to situations like the first example and
disallows the second one (or even deeper nestings)? I think this is
what the Solaris man page says.
--
---------------. drepper at gnu.org ,-. 1325 Chesapeake Terrace
Ulrich Drepper \ ,-------------------' \ Sunnyvale, CA 94089 USA
Cygnus Solutions `--' drepper at cygnus.com `------------------------
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/
Re: vfork specs [ In reply to ]
All true vfork implementations in all systems have had these restrictions,
whether cleared stated by their documentation or not. If you think about
it, the issue is inherent in the memory sharing behavior vfork is specified
to have.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/
Re: vfork specs [ In reply to ]
> Date: Fri, 15 Jan 1999 15:22:29 -0500
> From: Roland McGrath <roland@frob.com>
> Cc: GNU libc testers <libc-alpha@cygnus.com>,
> VGER gcc list <linux-gcc@vger.rutgers.edu>,
> VGER kernel list <linux-kernel@vger.rutgers.edu>
> X-Windows: some voids are better left unfilled.
>
> All true vfork implementations in all systems have had these restrictions,
> whether cleared stated by their documentation or not. If you think about
> it, the issue is inherent in the memory sharing behavior vfork is specified
> to have.
The Solaris manual page says:
NOTES
The use of vfork() for any purpose except as a prelude to an
immediate call to a function from the exec family, or to
_exit(), is not advised.
vfork() is unsafe in multi-thread applications.
This function will be eliminated in a future release. The
memory sharing semantics of vfork() can be obtained through
other mechanisms.
To avoid a possible deadlock situation, processes that are
children in the middle of a vfork() are never sent SIGTTOU
or SIGTTIN signals; rather, output or ioctls are allowed and
input attempts result in an EOF indication.
On some systems, the implementation of vfork() causes the
parent to inherit register values from the child. This can
create problems for certain optimizing compilers if
<unistd.h> is not included in the source calling vfork().
The Solaris vfork() does not permit the child's computation to be
interleaved with the parent's; after vfork(), the parent cannot run
until the child exits or calls exec. Except in multi-threaded
applications, when only the calling thread of control is suspended,
see the second paragraph from the manual page.
--
Geoffrey Keating <geoffk@ozemail.com.au>
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/
Re: vfork specs [ In reply to ]
> Assume this:
>
> void
> bar ()
> {
> pid_t p = baz ();
> if (p == 0)
> foo (0);
> }
> pid_t
> baz ()
> {
> return vfork ();
> }
The Single Unix Specification says:
: 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.
So this one is (if I interpret it correctly)
definitly bad code.
Regards
--
Stano
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/
Re: vfork specs [ In reply to ]
In message <199901160921.KAA04233@trillian.eunet.sk>, Stanislav Meduna
writes:
+-----
| > Assume this:
| >
| > pid_t
| > baz ()
| > {
| > return vfork ();
| > }
|
| The Single Unix Specification says:
|
| : 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.
|
| So this one is (if I interpret it correctly)
| definitly bad code.
+--->8
Yes. Return in the child -> the parent's stack pointer is now left pointing
to unknown data, because the stack is shared but the stack pointers
(obviously) aren't. (Unless #define vfork fork.)
vfork() is a horrible kludge. This is why.
--
brandon s. allbery [os/2][linux][solaris][japh] allbery@kf8nh.apk.net
system administrator [WAY too many hats] allbery@ece.cmu.edu
carnegie mellon / electrical and computer engineering KF8NH
We are Linux. Resistance is an indication that you missed the point.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/