Subject: Re: CYGWin fork() + Parent->Child Stack replicate algorithm
From: Christopher Faylor <[email-masked]>
To: "Faccini, Bruno" <[email-masked]>
Cc: [email-masked]
Date: Wed, 19 Sep 2001 13:52:16 -0400

Please check out the project web page for links to available information
and ports:  http://cygwin.com/ .

If you don't see what you need there, then the cygwin mailing list is
the best place to make observations or get questions answered.
Information on the mailing list is available at the project web page.

For your convenience, I've reset the Reply-To: address to point to the
cygwin mailing list.  I've also Cc'ed this reply there.

On Wed, Sep 19, 2001 at 06:14:49PM +0100, Faccini, Bruno wrote:
>
>Hello,
>
>I just found an email answer from you about a problem/question around the
>"CYGWin fork() + Parent->Child Stack replicate algorithm" that you told to
>be the author/main-developer.
>
>As an exercise to understand Win32 internals+API, I am currently trying to
>understand the internal mechanisms of the CYGWin "fork()" implementation on
>top of Win32 and I am particulary interested in the way you
>replicate+manipulate Child's Stack from the Parent's image (I am
>using/working-on the most recent "cygwin-1.3.[1,2,3]-1" pkgs actually). 
>Doing/looking-at this, I found that "alloc_stack_hard_way()" is
>handling+doing some condition/stuff I do not fully understand for now. Can
>you help/answer me ??
>If yes, here are the points I need to be explained/highlighted :
>	_ What do you mean by "alloc_stack_hard_way is executed when a fork
>is performed from something other than the non-main thread" (your
>comment/answer in the email thread where I found your references) ?? Do you
>meant "main thread" vs "non-main thread" in fact ?? Then, do you refer to
>the fact (and underlying Win32 Threads scheme) that "non-main threads" will
>have new Stack segments/Regions allocated and thus different address ranges
>than the "main" thread of both the Parent and the Child process ??
>	_ looking more indeep in both "alloc_stack()/alloc_stack_hard_way()"
>algorithm, I am a little-bit stuck with what you are checking+doing there
>... I tend to understand that you try to check and fix the case where
>"fork()" was called in/from a "Parent non-standard Stack
>situation/address-range" (am I right there ??), but what do you really
>address by the following "alloc_stack()/alloc_stack_hard_way()" code
>sequences, prior to "longjmp()" the Child to its Parent replicated Stack :
>----------------------------------------------------------------------------
>-------
>...
>// __inline__ void
>extern void
>alloc_stack_hard_way (child_info_fork *ci, volatile char *b)
>{
>  void *new_stack_pointer;
>  MEMORY_BASIC_INFORMATION m;
>  void *newbase;
>  int newlen;
>  LPBYTE curbot = (LPBYTE) sm.BaseAddress + sm.RegionSize;
>  bool noguard;
>
>  if (ci->stacktop > (LPBYTE) sm.AllocationBase && ci->stacktop < curbot)
>    {
>      newbase = curbot;
>      newlen = (LPBYTE) ci->stackbottom - (LPBYTE) curbot;
>      noguard = 1;
>    }
>  else
>    {
>      newbase = ci->stacktop;
>      newlen = (DWORD) ci->stackbottom - (DWORD) ci->stacktop;
>      noguard = 0;
>    }
>  if (!VirtualAlloc (newbase, newlen, MEM_RESERVE, PAGE_NOACCESS))
>....
>
>static void
>alloc_stack (child_info_fork *ci)
>{
>  /* FIXME: adding 16384 seems to avoid a stack copy problem during
>     fork on Win95, but I don't know exactly why yet. DJ */
>  volatile char b[ci->stacksize + 16384];
>
>  if (ci->type == PROC_FORK)
>    ci->stacksize = 0;		// flag to fork not to do any funny business
>  else
>    {
>      if (!VirtualQuery ((LPCVOID) &b, &sm, sizeof sm))
>	api_fatal ("fork: couldn't get stack info, %E");
>
>      if (sm.AllocationBase != ci->stacktop)
>	alloc_stack_hard_way (ci, b + sizeof (b) - 1);
>      else
>
>.....
>
>----------------------------------------------------------------------------
>---------
>
>You seem to assume+ignore some cases/scenarios here, like (and if I refer to
>"ci->[stack[top,size,bottom]]." stuff to describe the Parent's/fork()'ing
>current Stack allocation and the
>"sm.[AllocationBase,BaseAddress,RegionSize]" stuff to the Child's/fork()'ed
>current Stack allocation) "sm.AllocationBase" < "ci->stacktop" <
>"ci->stackbottom" < "curbot".
>
>Are these cases identified as not possible with Win32 Processes/Threads
>Stack allocation scheme ?? What about the Linker's "/STACK" option usage and
>behavior, or possible manual/explicit "VirtualAlloc()/VirtualFree()" earlier
>actions in the Parent/fork()'ing process/thread and for its Stack
>address-range ??
>
>And what about free'ing/VirtualFree() of the original but now possible
>unused/left pieces (like in the case of fully separate Parent and
>original/default Child Stacks adress ranges) ??
>
>Thank's in advance for your help/answer but also for your
>participation/great job to have this wonderfull CYGWin product/suite
>work/run so fine and for free + open-source.
>
>Best Regards.
>
>Bruno.
>
>Bruno Faccini - Tech. Mktg. Engr.
>E-Business & Communication Solutions
>Solutions Enabling & Services/Software Enabling (EMEA)
>Intel GmbH, Germany
>Phone (Intel office): +33-(0)146947228
>Phone (Mobile/GSM): +33-(0)607456727
>Fax: +33-(0)146947068
>email: [email-masked]
>
> <<Bruno Faccini (E-mail).vcf>> 

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/