X-Recipient: archive-cygwin AT delorie DOT com X-Spam-Check-By: sourceware.org Date: Thu, 16 Jul 2009 21:55:52 +0200 From: Corinna Vinschen To: cygwin AT cygwin DOT com Subject: Re: perl threads on 2008 R2 64bit = crash ( was: perl 5.10 threads on 1.5.25 = instant crash ) Message-ID: <20090716195552.GU27613@calimero.vinschen.de> Reply-To: cygwin AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com References: <20090715152139 DOT GA694 AT calimero DOT vinschen DOT de> <4A5DFDDF DOT 2000904 AT gmail DOT com> <20090715162243 DOT GL14502 AT ednor DOT casa DOT cgf DOT cx> <4A5E0AB1 DOT 9020201 AT gmail DOT com> <20090715185636 DOT GA16211 AT ednor DOT casa DOT cgf DOT cx> <4A5E2ED6 DOT 3070502 AT gmail DOT com> <20090715194539 DOT GZ27613 AT calimero DOT vinschen DOT de> <4A5E3F1F DOT 9040103 AT gmail DOT com> <20090716161219 DOT GP27613 AT calimero DOT vinschen DOT de> <4A5F59A1 DOT 1060902 AT gmail DOT com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <4A5F59A1.1060902@gmail.com> User-Agent: Mutt/1.5.19 (2009-02-20) 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 On Jul 16 17:47, Dave Korn wrote: > Corinna Vinschen wrote: > > > And that's what I get in the Perl testcase: > > > > (gdb) x/xw 0x7efdd000 > > 0x7efdd000: 0x0088ce68 > > (gdb) x/2xw 0x0088ce68 > > 0x88ce68: 0x0088400c 0x6103ce20 <-- Cygwin exception handler > > (gdb) x/2xw 0x0088400c > > 0x88400c: 0x00000000 0x00000001 <-- Huh? > > > > This looks wrong, doesn't it? The question is now, how and why does > > that happen? > > > Where's the 0x00000000 pointer coming from on 2008? Is it possible that > > the OS overwrote the entry because it appears to be an address in Perl's > > stack, so it's a potential security theat? > > The addresses are in the wrong order; SEH registration records should > always nest in the same way as stack call frames, i.e. unwinding toward > ascending memory addresses, but the second record is at a lower address than > the first, so the chain has been mangled somehow. Perhaps that breaks an > integrity check in the kernel? Where actually is $esp at the time; is the > bogus one in an already-released frame below $esp? Seems so. $esp is 0x88c8c0. > You might want to try again with a watchpoint: > > watch *(unsigned int*)0x88ce68 > > ... and see how and where that head entry gets set up and whether it > subsequently gets overwritten somehow. That was really helpful, Dave. Thank you! Here's the result: (gdb) br pthread_attr_init Breakpoint 2 at 0x610f42dc: file /home/corinna/src/cygwin/vanilla/winsup/cygwin/thread.cc, line 1909. (gdb) watch *(unsigned int*)0x88ce68 Hardware watchpoint 3: *(unsigned int *) 8965736 (gdb) c Continuing. Hardware watchpoint 3: *(unsigned int *) 8965736 Old value = 8978372 New value = 8929292 _cygtls::init_exception_handler (this=0x88ce64, eh=0x6103ce20 <_cygtls::handle_exceptions(_EXCEPTION_RECORD*, _exception_lis t*, _CONTEXT*, void*)>) at /home/corinna/src/cygwin/vanilla/winsup/cygwin/cygtls.cc:244 244 _except_list = ⪙ Current language: auto; currently c++ (gdb) p/x 8978372 $1 = 0x88ffc4 (gdb) p/x 8929292 $2 = 0x88400c (gdb) p $esp $3 = (void *) 0x883e78 (gdb) bt #0 _cygtls::init_exception_handler (this=0x88ce64, eh=0x6103ce20 <_cygtls::handle_exceptions(_EXCEPTION_RECORD*, _exception_lis t*, _CONTEXT*, void*)>) at /home/corinna/src/cygwin/vanilla/winsup/cygwin/cygtls.cc:244 #1 0x61033ff5 in dll_dllcrt0_1 (x=0x883edc) at /home/corinna/src/cygwin/vanilla/winsup/cygwin/dll_init.cc:321 #2 0x6103414f in dll_dllcrt0 (h=0x6eb70000, p=0x6eb79070) at /home/corinna/src/cygwin/vanilla/winsup/cygwin/dll_init.cc:302 #3 0x6eb77acf in _cygwin_dll_entry AT 12 () from /usr/lib/perl5/5.10/i686-cygwin/auto/threads/threads.dll ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ So this exception handler is installed as part of the Perl threads DLL initialization. But appanrelty the address is not valid anymore when leaving the DLL initialization. For testing I disabled the _my_tls.init_exception_handler (_cygtls::handle_exceptions); call in dll_init.cc:dll_dllcrt0_1() and re-ran the Perl testcase. Now it runs fine: $ perl ./perlthread.pl Testing threads... I'm a thread! Testing done Is it possible that we have to remove the exception handler before dll_dllcrt0_1 returns? Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- 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