http://bugs.winehq.org/show_bug.cgi?id=23472
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Keywords| |download URL| |http://www.pokerstars.eu/en | |/poker/download/ Component|-unknown |shell32 CC| |focht@gmx.net Ever Confirmed|0 |1 Summary|PokerStars crashes |PokerStars crashes/UI | |remains unresponsive on | |startup (dll detach | |notifications not sent for | |comctl32 on nested unload | |from shell32)
--- Comment #7 from Anastasius Focht focht@gmx.net 2013-12-10 14:18:04 CST --- Hello folks,
rechristening the bug for the current problem. The original problem was probably not present anymore.
The symptom is that either nothing happens (only few FIXME messages in terminal which are harmless) or a small "shrunk" main window is shown on startup that can be resized but no further GUI interaction is possible.
A Wine bug causes an exception but unfortunately the application internal 'global' exception handler eats this silently away (just logging it) which does more harm than good in the end.
--- snip ---- ... 0024:Call winex11.drv.WindowPosChanged(0001007c,00000000,00000014,0033c290,0033c290,0033c0c8,00000000,00000000) ret=7eb6e3f1 0024:Ret winex11.drv.WindowPosChanged() retval=00000000 ret=7eb6e3f1 0024:trace:win:WIN_CreateWindowEx hwnd 0x1007c cs 0,0 0x0 0024:Call window proc 0x7e2f1237 (hwnd=0x1007c,msg=WM_NCCREATE,wp=00000000,lp=0033c360) 0024:trace:seh:raise_exception code=c0000005 flags=0 addr=0x7e2f1237 ip=7e2f1237 tid=0024 0024:trace:seh:raise_exception info[0]=00000001 0024:trace:seh:raise_exception info[1]=7e2f1237 0024:trace:seh:raise_exception eax=7e2f1237 ebx=7ebb0000 ecx=00000000 edx=7bceaa08 esi=0033c360 edi=00000001 0024:trace:seh:raise_exception ebp=0033bf68 esp=0033bf3c cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00210206 0024:trace:seh:call_stack_handlers calling handler at 0xb4a400 code=c0000005 flags=0 --- snip ---
At the point of crash there is indeed nothing mapped at 0x7e2e4237 or near that range.
Going back in time ... reaching the big bang:
--- snip --- $ pwd /home/focht/.wine/drive_c/Program Files/PokerStars.EU
$ WINEDEBUG=+tid,+seh,+relay,+win,+msg,+commctrl,+module wine ./PokerStars.exe
log.txt 2>&1
...
0024:trace:module:process_attach (L"shell32.dll",(nil)) - START 0024:trace:module:process_attach (L"shlwapi.dll",(nil)) - START 0024:Call PE DLL (proc=0x7e3b5054,module=0x7e370000 L"shlwapi.dll",reason=PROCESS_ATTACH,res=(nil)) 0024:Call KERNEL32.DisableThreadLibraryCalls(7e370000) ret=7e3a54cb 0024:Ret KERNEL32.DisableThreadLibraryCalls() retval=00000001 ret=7e3a54cb 0024:Call KERNEL32.TlsAlloc() ret=7e3a54db 0024:Ret KERNEL32.TlsAlloc() retval=00000002 ret=7e3a54db 0024:Ret PE DLL (proc=0x7e3b5054,module=0x7e370000 L"shlwapi.dll",reason=PROCESS_ATTACH,res=(nil)) retval=1 0024:trace:module:process_attach (L"shlwapi.dll",(nil)) - END 0024:Call PE DLL (proc=0x7e487078,module=0x7e3f0000 L"shell32.dll",reason=PROCESS_ATTACH,res=(nil)) 0024:Call KERNEL32.DisableThreadLibraryCalls(7e3f0000) ret=7e42e4ef 0024:Ret KERNEL32.DisableThreadLibraryCalls() retval=00000001 ret=7e42e4ef 0024:Call KERNEL32.GetModuleFileNameW(7e3f0000,7e627060,00000104) ret=7e42e50e 0024:trace:module:GetModuleFileNameW L"C:\windows\system32\shell32.dll" 0024:Ret KERNEL32.GetModuleFileNameW() retval=0000001f ret=7e42e50e 0024:Ret PE DLL (proc=0x7e487078,module=0x7e3f0000 L"shell32.dll",reason=PROCESS_ATTACH,res=(nil)) retval=1 0024:trace:module:process_attach (L"shell32.dll",(nil)) - END 0024:Ret KERNEL32.LoadLibraryA() retval=7e3f0000 ret=007641c5 0024:Call KERNEL32.GetProcAddress(7e3f0000,00bd53b4 "SetCurrentProcessExplicitAppUserModelID") ret=007641d7 0024:Ret KERNEL32.GetProcAddress() retval=7e3fc9ec ret=007641d7 0024:Call shell32.SetCurrentProcessExplicitAppUserModelID(00bd4bb8 L"PokerStars.EU.Gui") ret=0076924c 0024:fixme:shell:SetCurrentProcessExplicitAppUserModelID L"PokerStars.EU.Gui": stub 0024:Ret shell32.SetCurrentProcessExplicitAppUserModelID() retval=80004001 ret=0076924c 0024:Call KERNEL32.FreeLibrary(7e3f0000) ret=0076925e 0024:trace:module:LdrUnloadDll (0x7e3f0000) 0024:trace:module:LdrUnloadDll (L"shell32.dll") - START 0024:trace:module:MODULE_DecRefCount (L"shell32.dll") ldr.LoadCount: 0 0024:trace:module:MODULE_DecRefCount (L"shlwapi.dll") ldr.LoadCount: 0 0024:Call PE DLL (proc=0x7e487078,module=0x7e3f0000 L"shell32.dll",reason=PROCESS_DETACH,res=(nil)) 0024:Call KERNEL32.LoadLibraryA(7e4cc04f "comctl32.dll") ret=7e486f96
--- snip ---
The app calls shell32.SetCurrentProcessExplicitAppUserModelID() which is late-bound -> shell32 dynamically loaded.
During unload of shell32.dll some cleanup takes place.
This causes the first-time load of comctl32.dll (no early binding):
shell32.dll DLL_PROCESS_DETACH -> SIC_Destroy() -> comctl32.ImageList_Destroy
Source: http://source.winehq.org/git/wine.git/blob/b6efcef7a7f005c752621fdce00f059e4...
--- snip --- BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) { TRACE("%p 0x%x %p\n", hinstDLL, fdwReason, fImpLoad);
switch (fdwReason) { case DLL_PROCESS_ATTACH: shell32_hInstance = hinstDLL; DisableThreadLibraryCalls(shell32_hInstance);
/* get full path to this DLL for IExtractIconW_fnGetIconLocation() */ GetModuleFileNameW(hinstDLL, swShell32Name, MAX_PATH); swShell32Name[MAX_PATH - 1] = '\0';
InitChangeNotifications(); break;
case DLL_PROCESS_DETACH: if (fImpLoad) break; SIC_Destroy(); FreeChangeNotifications(); release_typelib(); break; } return TRUE; } --- snip ---
Initialization of comctl32 is done (registration of window classes/procs):
--- snip --- 0024:trace:module:process_attach (L"comctl32.dll",(nil)) - START 0024:Call PE DLL (proc=0x7e3073b8,module=0x7e250000 L"comctl32.dll",reason=PROCESS_ATTACH,res=(nil)) 0024:trace:commctrl:DllMain 0x7e250000,1,(nil) 0024:Call KERNEL32.DisableThreadLibraryCalls(7e250000) ret=7e269e2a 0024:Ret KERNEL32.DisableThreadLibraryCalls() retval=00000001 ret=7e269e2a 0024:Call KERNEL32.GlobalAddAtomW(7e3099e0 L"CC32SubclassInfo") ret=7e269e43 0024:Ret KERNEL32.GlobalAddAtomW() retval=0000c010 ret=7e269e43 0024:trace:commctrl:DllMain Subclassing atom added: 0xc010 0024:Call gdi32.CreateBitmap(00000008,00000008,00000001,00000001,7e3099c0) ret=7e269ed0 0024:Ret gdi32.CreateBitmap() retval=00010024 ret=7e269ed0 0024:Call gdi32.CreatePatternBrush(00010024) ret=7e269ee7 0024:Ret gdi32.CreatePatternBrush() retval=00010025 ret=7e269ee7 ... 0024:Call winex11.drv.wine_get_gdi_driver(0000002e) ret=7e9d3208 0024:Ret winex11.drv.wine_get_gdi_driver() retval=7e23bce0 ret=7e9d3208 0024:Call winex11.drv.CreateDesktopWindow(00010020) ret=7eaf5193 0024:Ret winex11.drv.CreateDesktopWindow() retval=00000001 ret=7eaf5193 0024:Ret user32.GetDesktopWindow() retval=00010020 ret=7e9d327f 0024:Ret user32.LoadCursorW() retval=00020044 ret=7e260b04 0024:Call user32.RegisterClassW(0033ca7c) ret=7e260b70 0024:trace:win:alloc_winproc allocated 0xffff000d for W 0x7e260633 (14/4096 used) ... 0024:trace:win:alloc_winproc allocated 0xffff001d for W 0x7e2ea070 (30/4096 used) 0024:Ret user32.RegisterClassW() retval=0000c02d ret=7e2eb526 0024:Call user32.LoadCursorW(00000000,00007f00) ret=7e2f1b7e 0024:Ret user32.LoadCursorW() retval=00020044 ret=7e2f1b7e 0024:Call user32.RegisterClassW(0033ca74) ret=7e2f1c02 0024:trace:win:alloc_winproc allocated 0xffff001e for W 0x7e2f1237 (31/4096 used) ... 0024:Ret PE DLL (proc=0x7e3073b8,module=0x7e250000 L"comctl32.dll",reason=PROCESS_ATTACH,res=(nil)) retval=1 0024:trace:module:process_attach (L"comctl32.dll",(nil)) - END 0024:Ret KERNEL32.LoadLibraryA() retval=7e250000 ret=7e486f96 0024:Call KERNEL32.GetProcAddress(7e250000,7e4cc25d "ImageList_Destroy") ret=7e486fce 0024:Ret KERNEL32.GetProcAddress() retval=7e25b6a8 ret=7e486fce 0024:Call comctl32.ImageList_Destroy(00000000) ret=7e420360 0024:Ret comctl32.ImageList_Destroy() retval=00000000 ret=7e420360 0024:Call comctl32.ImageList_Destroy(00000000) ret=7e420371 0024:Ret comctl32.ImageList_Destroy() retval=00000000 ret=7e420371 --- snip ---
The loader recursion count is >1 during unload of comctl32 because we're nested, still in shell32.dll DLL_PROCESS_DETACH. Because of nesting level, the dll detach notification is not sent to comctl32.dll hence the unregistration of previously registered window classes/procs does not take place:
--- snip --- 0024:trace:module:free_modref unloading L"C:\windows\system32\shell32.dll" 0024:Call KERNEL32.FreeLibrary(7e250000) ret=7e487062 0024:trace:module:LdrUnloadDll (0x7e250000) 0024:trace:module:LdrUnloadDll (L"comctl32.dll") - START 0024:trace:module:MODULE_DecRefCount (L"comctl32.dll") ldr.LoadCount: 0 0024:trace:module:LdrUnloadDll END 0024:Ret KERNEL32.FreeLibrary() retval=00000001 ret=7e487062 0024:trace:module:free_modref unloading L"C:\windows\system32\shlwapi.dll" 0024:trace:module:free_modref unloading L"C:\windows\system32\comctl32.dll" 0024:Call KERNEL32.FreeLibrary(7e100000) ret=7e3073a2 0024:trace:module:LdrUnloadDll (0x7e100000) 0024:trace:module:LdrUnloadDll (L"uxtheme.dll") - START 0024:trace:module:MODULE_DecRefCount (L"uxtheme.dll") ldr.LoadCount: 0 0024:trace:module:LdrUnloadDll END 0024:Ret KERNEL32.FreeLibrary() retval=00000001 ret=7e3073a2 0024:trace:module:LdrUnloadDll END 0024:Ret KERNEL32.FreeLibrary() retval=00000001 ret=0076925e
--- snip ---
comctl32.dll gets unmapped but the window procs still remain registered. Later comctl32 is mapped again but the harm has already been done by having window atoms/classes/procs pointing to freed memory.
$ sha1sum PokerStarsInstallEU.exe 872eeddd632b5768b0010df830caf11fa051e753 PokerStarsInstallEU.exe
$ du -sh PokerStarsInstallEU.exe 27M PokerStarsInstallEU.exe
$ wine --version wine-1.7.8-135-gfaa355b
Regards