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

Ryan Johnson ryan.johnson@cs.utoronto.ca
Tue Feb 7 16:47:00 GMT 2012


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.

I also have a hypothesis to suggest: if cygwin1.dll loaded after 
cygiconv-2.dll (which I've seen happen), but initialized first (which it 
should, to preserve dependencies) then it's possible for 
dll_list::reserve_space to trip over a badly-placed cygiconv-2.dll 
before dll_list::alloc runs for cygiconv and checks its placement. This 
could be confirmed by comparing parent and child process maps.

BTW, what initialization do cyg*.dll do when they run? I have vague 
memories that they basically just check in with cygwin1.dll and then 
save their real init for some other function that is only called for 
non-forkee processes. If they do much of anything else, tho, it would be 
possible for dynamic dlls depending on static ones to init before their 
static dependencies. Even if that doesn't cause problems, is it possible 
that cygiconv isn't on the dll list yet for some reason, causing it to 
be treated as dynamically loaded? Again, my vague memory is that the dll 
list comes from the parent process, which would avoid the problem, but I 
can't remember for sure.

Ryan


--
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



More information about the Cygwin mailing list