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_en...@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