[Bug 23472] PokerStars crashes/UI remains unresponsive on startup (dll detach notifications not sent for comctl32 on nested unload from shell32)

wine-bugs at winehq.org wine-bugs at winehq.org
Tue Dec 10 14:18:04 CST 2013


http://bugs.winehq.org/show_bug.cgi?id=23472

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
           Keywords|                            |download
                URL|                            |http://www.pokerstars.eu/en
                   |                            |/poker/download/
          Component|-unknown                    |shell32
                 CC|                            |focht at 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 at 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/b6efcef7a7f005c752621fdce00f059e4af9a23d:/dlls/shell32/shell32_main.c#l1261

--- 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

-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
Do not reply to this email, post in Bugzilla using the
above URL to reply.
------- You are receiving this mail because: -------
You are watching all bug changes.



More information about the wine-bugs mailing list