This is the mail archive of the cygwin 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]
Other format: [Raw text]

Re: cygwin-1.7.10-1 fork - address space needed by ... already in use


On 2012-02-07 17:47, Ryan Johnson wrote:
> On 07/02/2012 11:14 AM, Corinna Vinschen wrote:
>> On Feb  7 16:43, Denis Excoffier wrote:
>>> I've also instrumented cygwin1.dll as suggested recently to Heiko Elger
>>> in http://cygwin.com/ml/cygwin/2012-02/msg00092.html
>>> [...]
>>> - the /proc/<pid>/maps of the processes involved in the fork failure look normal:
>>> ...
>>> 61262000-61470000 rw-p 00262000 C095:C492 13792273859134500   /usr/bin/cygwin1.dll
>>> 674C0000-674C1000 r--p 00000000 C095:C492 2251799814315820    /usr/bin/cygiconv-2.dll
>>> 674C1000-674D8000 r-xp 00001000 C095:C492 2251799814315820    /usr/bin/cygiconv-2.dll
>>> 674D8000-675B8000 rw-p 00018000 C095:C492 2251799814315820    /usr/bin/cygiconv-2.dll
>>> 675B8000-675B9000 r--p 000F8000 C095:C492 2251799814315820    /usr/bin/cygiconv-2.dll
>>> 675B9000-675BB000 rw-p 000F9000 C095:C492 2251799814315820    /usr/bin/cygiconv-2.dll
>>> 675BB000-675BC000 r--p 000FB000 C095:C492 2251799814315820    /usr/bin/cygiconv-2.dll
>>> 6AFC0000-6AFC1000 r--p 00000000 C095:C492 1407374884189126    /usr/bin/cygreadline7.dll
>>> ...
>> If this is the map of the forked child, then it's not exactly normal.
>> Consider that dll_list::reserve_space tries to reserve the memory which
>> is later supposed to be used for cygiconv-2.dll, but apparently
>> cygiconv-2.dll is already loaded.
>> 
>> What your report is missing is a bit more information.  We external
>> observes don't know if the error message in reserve_space actually
>> reported the address 0x674C0000, and we also don't know if the parent
>> process has the same layout as the child, or if it's different.  The
>> above information alone is not enough to evaluate the situation around
>> cygiconv-2.dll in your scenario.
>> 
>>> Now looking into dll_init.cc, i'm probably going to try the following: if
>>> VirtualAlloc (line 429, just before 'already occupied') fails, try it
>>> once more after waiting, say 100ms. Any comments?
>> Don't, it won't help.  Assuming my above assumptions are correct (but we
>> need proof), we seem to have a situation like this:
>> 
>> - cygiconv-2.dll has been loaded before cygwin1.dll
>> 
>> - cygwin1.dll tries to reserve space for later loading of cygiconv-2.dll
>>   but cygiconv-2.dll is already where it belongs.
>> 
>> - Since rsync is linked against cygiconv-2.dll, I'm wondering
>>   why it's in the list of runtime loaded DLLs.
> Denis, could you recompile cygwin1.dll to print out the list of dlls, and their types, on fork failure? IIRC, the list is pretty easy to traverse (singly-linked list rooted in a global variable or something similar). That might confirm or rule out Corinna's hypothesis.
You mean, something like this:

void
dll_list::reserve_space ()
{
  for (dll* d = dlls.istart (DLL_LOAD); d; d = dlls.inext ()) 
#ifdef PRISTINE
    if (!VirtualAlloc (d->handle, d->image_size, MEM_RESERVE, PAGE_NOACCESS))
      fabort ("address space needed by '%W' (%p) is already occupied",
        d->modname, d->handle);
#else
#define TYPE_SHOW(x) ((x) == DLL_NONE) ? "DLL_NONE" : ((x) == DLL_LINK) ? "DLL_LINK" : ((x) == DLL_LOAD) ? "DLL_LOAD" : ((x) == DLL_ANY) ? "DLL_ANY" : "DLL_(unknown)"
    if (!VirtualAlloc (d->handle, d->image_size, MEM_RESERVE, PAGE_NOACCESS)) {
#if 0
      for (dll* d_alt = dlls.istart (DLL_ANY); d_alt; d_alt = dlls.inext ()) {
        system_printf ("address space needed by '%W' (%p with type %d=%s) is perhaps already occupied",
          d_alt->modname, d_alt->handle, d_alt->type, TYPE_SHOW(d_alt->type));
      };  
#else
      for (dll* d_alt = dlls.start.next; d_alt; d_alt = d_alt.next ()) {
        system_printf ("address space needed by '%W' (%p with type %d=%s) is perhaps already occupied",
          d_alt->modname, d_alt->handle, d_alt->type, TYPE_SHOW(d_alt->type));
      };  
#endif
      fabort ("address space needed by '%W' (%p) is already occupied",
        d->modname, d->handle);
    };  
#endif
}


By the way, if someone can explain why in dll_init.h we have

  dll *istart (dll_type t)
  {
    hold_type = t;
    hold = &start;
    return inext (); 
  }

and not

  dll *istart (dll_type t)
  {
    hold_type = t;
    hold = &start;
    return hold; 
  }


Regards,

Denis Excoffier.


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


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