http://bugs.winehq.org/show_bug.cgi?id=10338
Summary: PE Explorer crashes when stopping the application Product: Wine Version: CVS/GIT Platform: PC-x86-64 URL: http://www.heaventools.com/download/pexsetup.exe OS/Version: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: wine-kernel AssignedTo: wine-bugs@winehq.org ReportedBy: Paul.Vriens.Wine@gmail.com
Created an attachment (id=9005) --> (http://bugs.winehq.org/attachment.cgi?id=9005) Adding some traces to kernel32 and ntdll
Install PE Explorer. Start the application and just exit it again (via the 'File' menu). It crashes in NtSetInformationThread. I've attached a '+tid,+seh,+process,+thread' trace. I've added some traces to some functions (diff is also attached). This is all done on a clean .wine and with current GIT.
http://bugs.winehq.org/show_bug.cgi?id=10338
--- Comment #1 from Paul Vriens Paul.Vriens.Wine@gmail.com 2007-11-07 06:45:41 --- Created an attachment (id=9006) --> (http://bugs.winehq.org/attachment.cgi?id=9006) debug log (without my extra traces)
http://bugs.winehq.org/show_bug.cgi?id=10338
--- Comment #2 from Paul Vriens Paul.Vriens.Wine@gmail.com 2007-11-07 06:46:23 --- Created an attachment (id=9007) --> (http://bugs.winehq.org/attachment.cgi?id=9007) debug log (with extra traces)
http://bugs.winehq.org/show_bug.cgi?id=10338
Lei Zhang thestig@google.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |download
http://bugs.winehq.org/show_bug.cgi?id=10338
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |focht@gmx.net
--- Comment #3 from Anastasius Focht focht@gmx.net 2007-11-08 06:30:48 --- Hello,
very interesting and indeed serious wine bug. The immediate cause is not easy to find .. took me some hours ;-)
The TlsXXX API calls trigger death from memory corruption, taking place earlier (corrupt TEB->TlsLinks list ptrs).
The application creates an additional thread, which shows splash screen and terminates it forcibly upon request (exit while shown or open file menu). CreateThread(splash) -> SuspendThread(splash)-> TerminateThread(splash) -> TlsAlloc (main thread, triggers death, because it walks the TlsLinks)
To make story short: the thread signal stack is too small. The signal handler (USR1) which handles thread suspension state overwrites parts of thread TEB. Because the splash thread TLS links are inserted at head of list, if threads TEB gets corrupted, any chained Tlslinks pointers will likely point to nirvana. Pity that wine has no guard page between TEB and thread signal stack to catch such catastrophic situation (due to technical reasons).
Unfortunately wine uses MINSIGSTKSZ from global linux signal headers in "dlls/ntdll/signal_i386.c" to calculate signal stack size to be reserved after TEB (TEB uses full page). My system (fedora core 7, 2.6.23.1-10.fc7) defines the following (signal.h/sigstack.h):
--- snip --- #define MINSIGSTKSZ 2048 #define SIGSTKSZ 8192 --- snip ---
My tests have shown that even a full page (4K) is too small. The signal stack size which seems to be safe to use must be at least SIGSTKSZ (2*PAGESIZE in this case). Maybe wine should make a safe guess above even that size, because during my debugging I inserted various TRACE snippets, implicitly shorting signal stack and triggering different corruption locations (making finding of real cause harder). It shouldn't hurt if it's a bit more like 2*SIGSTKSZ but it hurts seriously if signal stack is too small, triggering all sorts of internal corruptions/crashes, depending which TEB data gets referenced.
Use the following patch snippet to test my findings, assuming SIGSTKSZ is defined at least with 8192 or higher on your linux.
--- snip ---
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 0603e44..b705ce1 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -1334,7 +1334,7 @@ size_t get_signal_stack_total_size(void)
if (!signal_stack_size) { - size_t size = 4096, min_size = teb_size + max( MINSIGSTKSZ, 4096 ); + size_t size = 4096, min_size = teb_size + max( SIGSTKSZ, 4096 ); /* find the first power of two not smaller than min_size */ while (size < min_size) size *= 2; signal_stack_mask = size - 1;
--- snip ---
Thank you for this little challenge .. I really enjoyed it ;-)
Regards
http://bugs.winehq.org/show_bug.cgi?id=10338
--- Comment #4 from Paul Vriens Paul.Vriens.Wine@gmail.com 2007-11-08 06:59:52 --- Thanks a lot. It indeed fixes my issue. So how do we go about getting this into Wine? Ask Julliard?
http://bugs.winehq.org/show_bug.cgi?id=10338
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Resolution| |FIXED
--- Comment #5 from Alexandre Julliard julliard@winehq.org 2007-11-08 07:07:42 --- I committed a fix.
http://bugs.winehq.org/show_bug.cgi?id=10338
Dan Kegel dank@kegel.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #6 from Dan Kegel dank@kegel.com 2008-01-28 05:42:37 --- Closing all RESOLVED FIXED bugs older than four weeks.
http://bugs.winehq.org/show_bug.cgi?id=10338
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Version|CVS/GIT |unspecified
http://bugs.winehq.org/show_bug.cgi?id=10338
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Fixed by SHA1| |0156dbba4f4d1b1d55a359fea15 | |a217ff2a103ac Component|kernel32 |ntdll Version|unspecified |0.9.48.