Mailing-List: contact cygwin-developers-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT cygwin DOT com Delivered-To: mailing list cygwin-developers AT cygwin DOT com Date: Thu, 07 Nov 2002 12:18:31 -0500 From: Jason Tishler Subject: dll_list::detach() can stackdump To: Cygwin-Developers Mail-followup-to: Cygwin-Developers Message-id: <20021107171831.GA1752@tishler.net> MIME-version: 1.0 Content-type: multipart/mixed; boundary="Boundary_(ID_pSaPFhouBCEkiftzTFHigg)" User-Agent: Mutt/1.4i --Boundary_(ID_pSaPFhouBCEkiftzTFHigg) Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7BIT Content-disposition: inline I'm trying to debug a dll_list::detach() stackdump problem that I first triggered by a Cygwin Perl application. Specifically, the problem occurs at the following dll_init.cc line: void dll_list::detach (dll *d) { ... ***> if (d->count <= 0) ... } Note that I can only reproduce this problem on one Cygwin installation so far. FWIW, this is a partial installation (i.e., not all packages installed) with all standard Cygwin DLLs (except for the Cygwin DLL itself) rebased. However, all extra CPAN Perl extension module DLLs are not rebased due to an oversight. The first attachment is the a minimal Perl application that can also trigger the problem, the second is a C version. It appears that dlopen()-ing "many" DLLs (some rebased, some not) and then forking (two-levels) can trigger the problem. The third attachment is a patch (in a very loose sense of the word) that "fixes" the problem and adds some (hopefully) useful annotations: ... 284 5197991 [main] perl 620! dll_list::detach: JLT: myself->process_state = C1 422 5198413 [main] perl 620! dll_list::detach: JLT: d = 0xB20000 340 5198753 [main] perl 620! dll_list::detach: JLT: VirtualFree(d = 0xB20000, d->name = c:\Program Files\Hewlett-Packard\SANmaster\usr\lib\perl5\5.8.0\cygwin-multi-64int\auto\Socket\Socket.dll) 489 5199242 [main] perl 620! dll_list::detach: JLT: loaded_dlls = 5 *>860 5200102 [main] perl 620! dll_list::detach: JLT: skipping bad d = 0xB00000 440 5200542 [main] perl 620! dll_list::detach: JLT: myself->process_state = C1 414 5200956 [main] perl 620! dll_list::detach: JLT: d = 0x67F70000 431 5201387 [main] perl 620! dll_list::detach: JLT: VirtualFree(d = 0x67F70000, d->name = c:\cygwin\bin\cygexpat-0.dll) 339 5201726 [main] perl 620! dll_list::detach: JLT: loaded_dlls = 4 ... The above seems to imply that a bad address is passed into cygwin_detach_dll() for one of the DLLs. Unfortunately, I don't understand why. FWIW, in this case, the skipped DLL is the CPAN XML::Parser's Expat.dll which was not rebased. Any hints on how to debug this further is greatly appreciated. Thanks, Jason -- PGP/GPG Key: http://www.tishler.net/jason/pubkey.asc or key servers Fingerprint: 7A73 1405 7F2B E669 C19D 8784 1AFD E4CC ECF4 8EF6 --Boundary_(ID_pSaPFhouBCEkiftzTFHigg) Content-type: application/x-perl; NAME=stack.pl Content-transfer-encoding: quoted-printable Content-disposition: attachment; filename=stack.pl #! /usr/bin/perl=0A=0ABEGIN {=0A $smhome =3D "/tmp/sm";=0A unshift(@INC, "$= smhome/usr/lib/perl5/5.8.0","$smhome/usr/lib/perl5/5.8.0/cygwin-multi-64int= ");=0A}=0A=0Ause lib "$smhome/usr/lib/perl5/site_perl/5.8.0";=0A=0Ause Engl= ish;=0Ause XML::Parser; # dll=0Ause XML::Simple;=0Ause Mail::Sender;=0Ause = LWP::UserAgent;=0Ause HTTP::Request::Common;=0Ause HTTP::Status;=0Ause POSI= X;=0Ause Compress::Zlib; # dll=0Ause File::Basename;=0A=0Asystem("uname -a"= );=0A= --Boundary_(ID_pSaPFhouBCEkiftzTFHigg) Content-type: text/plain; charset=us-ascii; NAME=dll.cc Content-transfer-encoding: 7BIT Content-disposition: attachment; filename=dll.cc #include #include #include #include #include #include int main(int argc, const char* argv[]) { for (int i = 1; i < argc; i++) { const char *filename = argv[i]; void* h = dlopen(filename, RTLD_LAZY); if (!h) { printf ("%s: %s\n", filename, dlerror()); exit(1); } } pid_t pid = fork(); if (pid > 0) wait(0); else if (pid == 0) execl("/bin/uname", "/bin/uname", "-a", 0); exit(0); } --Boundary_(ID_pSaPFhouBCEkiftzTFHigg) Content-type: text/plain; charset=us-ascii; NAME=dll_init.cc.diff Content-transfer-encoding: 7BIT Content-disposition: attachment; filename=dll_init.cc.diff Index: dll_init.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/dll_init.cc,v retrieving revision 1.32 diff -u -p -r1.32 dll_init.cc --- dll_init.cc 2 Nov 2002 03:31:15 -0000 1.32 +++ dll_init.cc 7 Nov 2002 16:11:14 -0000 @@ -187,6 +187,15 @@ dll_list::detach (dll *d) if (!myself || myself->process_state == PID_EXITED) return; + if (IsBadReadPtr (d, sizeof (dll))) + { + system_printf ("JLT: skipping bad d = %p", d); + return; + } + + system_printf ("JLT: myself->process_state = %lx", myself->process_state); + system_printf ("JLT: d = %p", d); + if (d->count <= 0) system_printf ("WARNING: try to detach an already detached dll ..."); else if (--d->count == 0) @@ -199,8 +208,14 @@ dll_list::detach (dll *d) loaded_dlls--; if (end == d) end = d->prev; + + system_printf ("JLT: VirtualFree(d = %p, d->name = %s)", d, d->name); + system_printf ("JLT: loaded_dlls = %d", loaded_dlls); + VirtualFree (d, 0, MEM_RELEASE); } + else + system_printf ("JLT: --d->count, d = %p, count = %d", d, d->count); } /* Initialization for all linked DLLs, called by dll_crt0_1. */ --Boundary_(ID_pSaPFhouBCEkiftzTFHigg)--