How to make child of failed fork exit cleanly?

Ryan Johnson ryan.johnson@cs.utoronto.ca
Wed May 4 20:28:00 GMT 2011


On 04/05/2011 2:48 PM, Ryan Johnson wrote:
> On 04/05/2011 11:58 AM, Christopher Faylor wrote:
>> On Wed, May 04, 2011 at 05:33:57PM +0200, Corinna Vinschen wrote:
>>>> That said, I've implemented what you suggested (reversing the sense
>>>> of dll::has_dtors until fork fixup completes), and it seems to
>>>> behave properly. I still wonder, though: can we expect all dlls to
>>>> behave properly if (from their perspective) some library they
>>>> communicate with has ceased to exist without detaching?
>>> It's a good assumption for a start.  If it turns out to be incorrect,
>>> we can take another look.
>> Wouldn't this do what's required pretty simply?
>>
>> cgf
>>
>> --- dll_init.cc 2 May 2011 15:28:34 -0000       1.81
>> +++ dll_init.cc 4 May 2011 15:57:26 -0000
>> @@ -37,6 +37,8 @@ static bool dll_global_dtors_recorded;
>>   void
>>   dll_global_dtors ()
>>   {
>> +  if (in_forkee)
>> +    return;
>>     int recorded = dll_global_dtors_recorded;
>>     dll_global_dtors_recorded = false;
>>     if (recorded&&  dlls.start.next)
>
> I favor one change in dll_init.h instead:
>    void run_dtors ()
>    {
> -    if (has_dtors)
> +    if (has_dtors&&  !in_forkee)
>
>        {
>         has_dtors = 0;
>         p.run_dtors ();
>        }
>    }

> 2. once frok::child's first call to sync_with_parent returns, the 
> statically linked dlls are fully initialized and (in theory) need to 
> be finalized if the process exits. At least, that's the impression I 
> got from Corinna's response. It does make sense in a way (one might 
> ask why the finalizers exist if they don't need to run?). However, 
> it's equally easy to argue that the child doesn't really "exist" until 
> the fork completes successfully, which I tend to favor given undefined 
> behavior that would arise if dlls share state with each other. It's 
> easy to implement either way, though (I've already tested Corinna's 
> suggestion, it's just a few more lines of code than the above). We 
> just need to decide which we like better.
Update: testing with an app that loads dlls dynamically gives access 
violations while trying to unload statically-linked libraries (namely, 
cyggcc_s, whose copied-over state includes invalid pointers to the dlls 
dynamically-loaded-in-parent-but-not-child).

I therefore strongly favor cgf's approach.

Ryan



More information about the Cygwin-developers mailing list