X-Recipient: archive-cygwin AT delorie DOT com X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE X-Spam-Check-By: sourceware.org Subject: Re: cygwin-1.7.10-1 fork - address space needed by ... already in use Mime-Version: 1.0 (Apple Message framework v1257) Content-Type: text/plain; charset=us-ascii From: Denis Excoffier In-Reply-To: <4F31559B.6060600@cs.utoronto.ca> Date: Tue, 7 Feb 2012 23:48:35 +0100 Message-Id: References: <33279157 DOT post AT talk DOT nabble DOT com> <20120207154359 DOT GA2952 AT qp9482> <20120207161428 DOT GB12159 AT calimero DOT vinschen DOT de> <4F31559B DOT 6060600 AT cs DOT utoronto DOT ca> To: cygwin AT cygwin DOT com Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by delorie.com id q17Mn1cO030538 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//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