This is the mail archive of the cygwin-developers@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Current CVS repository: vfork/rsync still failing on NT4


On Mon, Sep 03, 2001 at 03:08:08PM -0400, Jonathan Kamens wrote:
>I am still seeing rsync failing when started from ash, with the
>current CVS repository (updated and compiled from scratch a couple of
>hours ago) and the current ash release.
>
>I saw a recent message from Christopher Faylor indicating that he
>couldn't duplicate this problem,

This "recent" email was apparently from a month ago.

>I've also attached two strace output files, one from running my sample
>program as described above, and one from running it with the first
>argument being "fork" instead of "vfork".  Although, as I said, the
>problem doesn't occur under strace, note that there are differences in
>the strace output in the two cases.  For example:
>
>* In the vfork case, shortly after rsync starts up, it closes several
>  file handles:
>
>    115   12721 [main] rsync 112 dtable::vfork_child_fixup: here
>    127   12848 [main] rsync 112 fhandler_base::close: handle 0x100
>    134   12982 [main] rsync 112 fhandler_base::close: handle 0x1E0
>    121   13103 [main] rsync 112 fhandler_base::close: handle 0x14C
>
>  This doesn't happen in the fork case.

These are from vfork_child_fixup.  They close handles that were inherited
from the parent which should not be inherited from the parent.

Vfork is mainly smoke and mirrors.  A call to vfork contines to execute
in the current process but first it returns a pid of 0 so that process
will execute code intended for the child in a UNIX system.  Before returning
the zero, vfork makes a copy of the current fd table so that closing an
fd in the "child" will not affect the "parent".

The process continues to execute until it hits some type of exec call.
The exec call is translated into a spawn NO_WAIT call and the new
process is started via this mechanism.  After execing, the "child"
process no longer should exist, so the spawn code longjmps back to the
original vfork call.  The previously opened fds are closed and the
parent's fd table is restored.  vfork() then returns the pid of the
just-spawned process.

Meanwhile, the just-spawned child notices that it has been spawned as
the result of a vfork and closes the extra file handles.  That is what
you're seeing above.

This all relies on the fact that the child in a vfork call can affect
just about everything in the parent except for the parent's fds.
The assumption is that you don't return from the call that invoked the
vfork.

The assumption is also that all of this is much faster than the
slow method that cygwin uses to implement fork().

>* The vfork case never calls sync_with_parent after the child rsync
>  process is launched after the vfork.

Since vfork uses a different mechanism than fork it should never call
sync_with_parent.

>I've also attached the gdb output from setting error_start and
>catching the failure in the child rsync process.  It doesn't look
>particularly useful to me, but perhaps someone else will be able to
>derive something useful out of it.

I'm sorry to say that your test case works fine for me under Windows 2000.
Maybe the description above will enable you to track down what is happening.

cgf


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]