[Bug 38987] tlReader 10.x crashes when searching dictionary ( wxWidgets 2.9.4 questionable theming support detection via comctl32 v6 version resource )

wine-bugs at winehq.org wine-bugs at winehq.org
Mon Apr 2 08:47:05 CDT 2018


https://bugs.winehq.org/show_bug.cgi?id=38987

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|tlReader 10.x crashes when  |tlReader 10.x crashes when
                   |searching dictionary        |searching dictionary
                   |                            |(wxWidgets 2.9.4
                   |                            |questionable theming
                   |                            |support detection via
                   |                            |comctl32 v6 version
                   |                            |resource)
          Component|-unknown                    |comctl32

--- Comment #12 from Anastasius Focht <focht at gmx.net> ---
Hello folks again,

after working around bug 32342 the next crash:

--- snip ---
$ pwd
/home/focht/wineprefix32/drive_c/Program Files/tlReader

$ WINEDEBUG=+seh,+relay,+snoop wine ./tlReader.exe >>log.txt 2>&1
...
002e:CALL wxmsw294u_core_vc_custom.?Get at wxUxThemeEngine@@SAPAV1 at XZ(<unknown,
check return>) ret=041c4873
002e:RET  wxmsw294u_core_vc_custom.?Get at wxUxThemeEngine@@SAPAV1 at XZ()
retval=00000000 ret=041c4873
002e:trace:seh:raise_exception code=c0000005 flags=0 addr=0x41c4875 ip=041c4875
tid=002e
002e:trace:seh:raise_exception  info[0]=00000000
002e:trace:seh:raise_exception  info[1]=00000000
002e:trace:seh:raise_exception  eax=00000000 ebx=134f60d8 ecx=81f1fc84
edx=04124c00 esi=134f7b30 edi=134f7b30
002e:trace:seh:raise_exception  ebp=00000000 esp=0032f430 cs=0023 ds=002b
es=002b fs=0063 gs=006b flags=00210216
002e:trace:seh:call_stack_handlers calling handler at 0x45874cf code=c0000005
flags=0
002e:trace:seh:call_stack_handlers handler at 0x45874cf returned 1
002e:trace:seh:call_stack_handlers calling handler at 0x45873b8 code=c0000005
flags=0 
--- snip ---

Disassembly of caller code:

--- snip ---
...
04084855  MOV DWORD PTR FS:[0],EAX
0408485B  MOV EAX,DWORD PTR SS:[ESP+0EC]
04084862  MOV EDI,DWORD PTR SS:[ESP+0E8]
04084869  MOV DWORD PTR SS:[ESP+14],EAX
0408486D  CALL DWORD PTR DS:[<&wxmsw294u_core_vc_custom.wxUxThemeEngine::Get>]
04084873  MOV EBP,EAX                           ; NULL
04084875  MOV ECX,DWORD PTR SS:[EBP]            ; *boom*
04084878  PUSH OFFSET 0455D064                  ; UNICODE "SCROLLBAR"
0408487D  PUSH 0
0408487F  CALL ECX
...
--- snip ---

Caller module mapping:

--- snip ---
Executable modules
  Base = 03670000
  Size = 011B4000 (18563072.)
  Entry = 0434B2F9
  Name = wxwebkit
  Type =
  File version =
  Static links = ADVAPI32, GDI32, gdiplus, icuin40, icuuc40, jscore, KERNEL32,
libcairo-2, libcurl, libxml2, libxslt, MSVCP100, MSVCR100, ole32, SHLWAPI,
sqlite3, USER32, USP10, VERSION, WINMM, WSOCK32, wxbase294u_vc_custom,
wxmsw294u_core_vc_custom
  Path = C:\Program Files\tlReader\wxwebkit.dll
--- snip ---

WxWidgets UxTheme code for the getter:

https://github.com/wxWidgets/wxWidgets/blob/v2.9.4/src/msw/uxtheme.cpp#L78

--- snip ---
wxUxThemeEngine* wxUxThemeEngine::Get()
{
    // we assume that themes are only used in the main thread hence no need for
    // critical section here
    if ( ms_isThemeEngineAvailable == -1 )
    {
        // we're called or the first time, check if the themes are available
        ms_themeEngine = new wxUxThemeEngine;
        if ( !ms_themeEngine->Initialize() )
        {
            // can't use themes, probably because the system doesn't support
            // them, don't do it again
            delete ms_themeEngine;
            ms_themeEngine = NULL;

            ms_isThemeEngineAvailable = false;
        }
        else // initialized ok
        {
            ms_isThemeEngineAvailable = true;
        }
    }

    return ms_themeEngine;
}
--- snip ---

The NULL ptr return resulted from this:

https://github.com/wxWidgets/wxWidgets/blob/v2.9.4/src/msw/uxtheme.cpp#L104

--- snip ---
bool wxUxThemeEngine::Initialize()
{
    if ( wxApp::GetComCtl32Version() < 600 )
    {
        // not using theme-aware comctl32.dll anyhow, don't even try to use
        // themes
        return false;
    }

    // we're prepared to handle the errors
    wxLogNull noLog;

    if ( !m_dllUxTheme.Load(wxT("uxtheme.dll")) )
        return false;
--- snip ---

Most likely there is some missing check of uxtheme engine availability and the
caller just does 'wxUxThemeEngine::Get()->foobar()'.
One could argue that wxWidgets could have done better error handling here.
In fact they do a lot of checks ... maybe one code path missed it.

The comctl32 dll version check seems kinda questionable though.

https://github.com/wxWidgets/wxWidgets/blob/v2.9.4/src/msw/app.cpp#L917

--- snip ---
int wxApp::GetComCtl32Version()
{
    // cache the result
    //
    // NB: this is MT-ok as in the worst case we'd compute s_verComCtl32 twice,
    //     but as its value should be the same both times it doesn't matter
    static int s_verComCtl32 = -1;

    if ( s_verComCtl32 == -1 )
    {
        // we're prepared to handle the errors
        wxLogNull noLog;

        // we don't want to load comctl32.dll, it should be already loaded but,
        // depending on the OS version and the presence of the manifest, it can
        // be either v5 or v6 and instead of trying to guess it just get the
        // handle of the already loaded version
        wxLoadedDLL dllComCtl32(wxT("comctl32.dll"));
        if ( !dllComCtl32.IsLoaded() )
        {
            s_verComCtl32 = 0;
            return 0;
        }

        // try DllGetVersion() for recent DLLs
        s_verComCtl32 = CallDllGetVersion(dllComCtl32);

        // if DllGetVersion() is unavailable either during compile or
        // run-time, try to guess the version otherwise
        if ( !s_verComCtl32 )
        {
            // InitCommonControlsEx is unique to 4.70 and later
            void *pfn = dllComCtl32.GetSymbol(wxT("InitCommonControlsEx"));
            if ( !pfn )
            {
                // not found, must be 4.00
                s_verComCtl32 = 400;
            }
            else // 4.70+
            {
                // many symbols appeared in comctl32 4.71, could use any of
                // them except may be DllInstall()
                pfn = dllComCtl32.GetSymbol(wxT("InitializeFlatSB"));
                if ( !pfn )
                {
                    // not found, must be 4.70
                    s_verComCtl32 = 470;
                }
                else
                {
                    // found, must be 4.71 or later
                    s_verComCtl32 = 471;
                }
            }
        }
    }

    return s_verComCtl32;
}
--- snip ---

There is proper manifest data in binaries, specifically common controls v6:

--- snip ---
$ pwd
/home/focht/wineprefix32/drive_c/Program Files/tlReader

$ grep -aPo '.{0,20}Microsoft.Windows.Common-Controls.{0,20}' *{.dll,.exe}
DicLib.dll: type="win32" name="Microsoft.Windows.Common-Controls"
version="6.0.0.0" 
jscore.dll: type="win32" name="Microsoft.Windows.Common-Controls"
version="6.0.0.0" 
wxActiveX.dll: type="win32" name="Microsoft.Windows.Common-Controls"
version="6.0.0.0" 
wxbase294u_vc_custom.dll: type="win32" name="Microsoft.Windows.Common-Controls"
version="6.0.0.0" 
wxmsw294u_adv_vc_custom.dll: type="win32"
name="Microsoft.Windows.Common-Controls" version="6.0.0.0" 
wxmsw294u_core_vc_custom.dll: type="win32"
name="Microsoft.Windows.Common-Controls" version="6.0.0.0" 
wxmsw294u_html_vc_custom.dll: type="win32"
name="Microsoft.Windows.Common-Controls" version="6.0.0.0" 
wxmsw294u_stc_vc_custom.dll: type="win32"
name="Microsoft.Windows.Common-Controls" version="6.0.0.0" 
wxwebkit.dll: type="win32" name="Microsoft.Windows.Common-Controls"
version="6.0.0.0" 
tlReader.exe: type="win32" name="Microsoft.Windows.Common-Controls"
version="6.0.0.0" 
Uninstall.exe: type="win32" name="Microsoft.Windows.Common-Controls"
version="6.0.0.0" 
--- snip ---

Wine provides two variants of 'comctl32' as Windows does: 

* v5 under traditional location -> 'C:\Windows\system32' (or WoW64 locations)
* v6 under 'C:\Windows\WinSxS\', available as a side-by-side assembly with
theming support.

Corresponding trace log showing manifest is taken into account:

--- snip ---
...
0041:trace:actctx:get_manifest_in_module looking for res #0002 in module
0x9d0000 L"C:\\Program Files\\tlReader\\wxmsw294u_core_vc_custom.dll"
0041:trace:actctx:parse_manifest parsing manifest loaded from (null) base dir
(null)
0041:trace:actctx:parse_assembly_elem (0x32de24)
0041:trace:actctx:parse_assembly_identity_elem
name=L"Microsoft.Windows.Common-Controls" version=6.0.0.0 arch=L"x86"
0041:trace:actctx:parse_dependent_assembly_elem adding
name=L"Microsoft.Windows.Common-Controls" version=6.0.0.0 arch=L"x86"
0041:trace:actctx:lookup_assembly looking for
name=L"Microsoft.Windows.Common-Controls" version=6.0.0.0 arch=L"x86"
0041:trace:ntdll:FILE_CreateFile handle=0x32e1f0 access=80100000
name=L"\\??\\C:\\windows\\winsxs\\manifests" objattr=00000040 root=(nil)
sec=(nil) io=0x32e1f4 alloc_size=(nil) attr=00000000 sharing=00000003 disp=1
options=00000021 ea=(nil).0x00000000
0041:trace:ntdll:FILE_CreateFile handle=0x32e1f0 access=80100000
name=L"\\??\\C:\\windows\\winsxs\\manifests\\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef.manifest"
objattr=00000040 root=(nil) sec=(nil) io=0x32e1b0 alloc_size=(nil)
attr=00000000 sharing=00000001 disp=1 options=00000010 ea=(nil).0x00000000
0041:trace:actctx:get_manifest_in_manifest_file loading manifest file
L"\\??\\C:\\windows\\winsxs\\manifests\\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef.manifest"
0041:trace:ntdll:NtQueryInformationFile
(0x24,0x32e1a0,0x32e1a8,0x00000008,0x00000014)
0041:trace:actctx:parse_manifest parsing manifest loaded from
L"\\??\\C:\\windows\\winsxs\\manifests\\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef.manifest"
base dir
L"x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef"
0041:trace:actctx:parse_assembly_elem (0x32dce4)
0041:trace:actctx:parse_assembly_identity_elem
name=L"Microsoft.Windows.Common-Controls" version=6.0.2600.2982 arch=L"x86"
0041:trace:actctx:parse_file_elem name=L"comctl32.dll" 
...
0041:trace:module:find_dll_file found
L"C:\\windows\\winsxs\\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef\\comctl32.dll"
for L"comctl32.dll"
0041:trace:actctx:RtlFindActivationContextSectionString 00000001 (null) 2
L"comctl32.dll" 0x32d538
0041:trace:actctx:RtlQueryInformationActivationContext 00000000 0x11dee8
0x32d55c 3 0x12cfc8 1024 0x32d52c
0041:trace:module:find_dll_file found
L"C:\\windows\\winsxs\\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef\\comctl32.dll"
for L"comctl32.dll"
0041:trace:ntdll:FILE_CreateFile handle=0x32d574 access=80100000
name=L"\\??\\C:\\windows\\winsxs\\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef\\comctl32.dll"
objattr=00000040 root=(nil) sec=(nil) io=0x32d578 alloc_size=(nil)
attr=00000000 sharing=00000005 disp=1 options=00000060 ea=(nil).0x00000000
0041:trace:module:get_load_order looking for
L"C:\\windows\\winsxs\\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef\\comctl32.dll"
0041:trace:module:get_load_order got hardcoded default for
L"C:\\windows\\winsxs\\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef\\comctl32.dll" 
...
0041:trace:module:load_dll
L"C:\\windows\\winsxs\\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef\\comctl32.dll"
is a fake Wine dll
0041:trace:module:load_builtin_dll Trying built-in L"comctl32.dll" 
...
0041:trace:module:load_builtin_callback loaded comctl32.dll 0x12b610 0x7dd70000
0041:trace:loaddll:load_builtin_dll Loaded
L"C:\\windows\\system32\\comctl32.dll" at 0x7dd70000: builtin 
...
0041:Call comctl32.InitCommonControls() ret=00a9ee2a
0041:Ret  comctl32.InitCommonControls() retval=7dd8d037 ret=00a9ee2a
...
0041:Call KERNEL32.GetModuleHandleW(04fdfb88 L"comctl32.dll") ret=008d758c
0041:Ret  KERNEL32.GetModuleHandleW() retval=7dd70000 ret=008d758c 
...
0041:Call comctl32.DllGetVersion(0032ef64) ret=00a9df26
0041:Ret  comctl32.DllGetVersion() retval=00000000 ret=00a9df26
...
--- snip ---

Even if common control v6 activation context is there, the dll version check
will still fail (WinSxS one has v5.81 version in resources)

Source:

https://source.winehq.org/git/wine.git/blob/79f93ecf429f42db15bc14f276045fdad35cef13:/dlls/comctl32/comctl32.rc#l108

--- snip ---
 108 #define WINE_FILEDESCRIPTION_STR "Wine Common Controls"
 109 #define WINE_FILENAME_STR "comctl32.dll"
 110 #define WINE_FILEVERSION COMCTL32_VERSION, COMCTL32_VERSION_MINOR, 4704,
1100
 111 #define WINE_FILEVERSION_STR "5.81"
 112 #define WINE_PRODUCTVERSION WINE_FILEVERSION
 113 #define WINE_PRODUCTVERSION_STR WINE_FILEVERSION_STR
--- snip ---

It seems newer wxWidgets dropped these questionable checks as part of larger
cleanup:

https://trac.wxwidgets.org/ticket/17120

-> Pull request https://github.com/wxWidgets/wxWidgets/pull/82

https://github.com/wxWidgets/wxWidgets/pull/82/commits/03b243da21da917fe895c91490c13694971c5f0d

One can't force all the FOSS/commercial projects to upgrade their projects to
use a newer wxWidgets version.
Wine should provide reasonable compatibility, that is proper version resource
for v6-based common controls.

$ sha1sum tlReader_10.1.0.2004.exe 
0c09fb0d0d5efc89cb8ff5bc12ce15347e04a63e  tlReader_10.1.0.2004.exe

$ du -sh tlReader_10.1.0.2004.exe 
31M    tlReader_10.1.0.2004.exe

$ wine --version
wine-3.5

Regards

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