Crash in mfc80u.dll!CComCtlWrapper::_InitCommonControlsEx



  • Beim Versuch einen Dialog zu erzeugen ( CDialog::Create(UINT, CWnd*) ) crasht eines unserer Programme in mfc80u.dll!CComCtlWrapper::_InitCommonControlsEx .

    Die Crashende Zeile befindet sich im AFX_ISOLATIONAWARE_FUNC Makro:
    result=m__##name##args; \

    Also da wo er die DLL Funktion über den Funktionszeiger aufrufen möchte. Im Funktionszeiger steht nur dummerweise kompletter Müll drinnen (nicht 0, aber auch keine gültige Adresse - an der Adresse ist kein Speicher gemappt -> Access Violation).

    Eim paar Infos zum Drumherum:
    * Windows 7 SP1 64 Bit
    * Es ist ein 32 Bit Prozess (WoW64)
    * IDE/Compiler/MFC-Version = Visual Studio 2005
    * Der CDialog::Create Aufruf befindet sich in einer DLL, die wiederrum aus einer anderen DLL aufgerufen wird.
    * Beide DLLs sind "regular, using the shared MFC DLL" (= _AFXDLL und _USRDLL definiert)
    * Die .exe ist ebenfalls eine MFC .exe (verwendet ebenfalls die DLL Version der MFC)
    * Die EXE sowie alle DLLs sind mit dem selben Compiler und kompatiblen Compiler-Einstellungen gebaut
    * Das selbe Programm läuft auf Windows XP SP2 32 Bit wunderbar
    * Im Debug-Mode konnten wir das Problem bisher nicht nachvollziehen (ebenfalls Windows 7 SP1 64 Bit, allerdings anderer PC)

    AFX_MANAGE_STATE Aufrufe sind folgendermassen vorhanden:

    // "Äussere" DLL:
    void OuterDllUserInterfaceThread::Run() // überschreibt CWinThread::Run
    {
        AFX_MANAGE_STATE(AfxGetStaticModuleState());
        OuterDllDialog().DoModal();
    }
    
    void OuterDllDialog::SomeButtonHandler()
    {
        // hier KEIN AFX_MANAGE_STATE! (wäre es hier nötig?)
        InnerDllFunction();
    }
    
    // "Innere" DLL:
    
    void InnerDllFunction()
    {
        AFX_MANAGE_STATE(AfxGetStaticModuleState());
        ...
        InnerDllDialog dlg(...);
        BOOL rc = dlg.Create(InnerDllDialog::IDD, parentWindow); // <-- Crash hier
        ...
    }
    

    Weiss jemand was hier schief läuft?
    Oder hat jemand Tipps was man probieren könnte um der Sache auf den Grund zu gehen?



  • Hm.
    Folgendes hat den Fehler anscheinend behoben:

    #ifdef _UNICODE
    #if defined _M_IX86
    #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
    #elif defined _M_IA64
    #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
    #elif defined _M_X64
    #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
    #else
    #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
    #endif
    #endif
    

    Wobei ich es nicht ganz verstehe.
    Also wie das Fehlen des Manifest-Eintrags zu Schrottwerten in den Funktionszeigern von CComCtlWrapper führen kann...
    (NULL Werte hätte ich verstanden, aber Schrottwerte... pfuh.)


  • Mod

    Ganz einfach: Durch das fehlende Manifest wird die COMCTL32 evtl. zweimal geladen... evtl. passieren noch mehr böse Dinge, weil Deine DLL wie die EXE auch die MFC verwenden. Aber Deine DLL nicht die gleice COMCTL32 verwendet wie die MFC/EXE



  • Ganz ist mir das immer noch nicht klar. Also warum es ein Problem gibt. Sollen halt verschiedene COMCTL32 geladen werden, is mir ja wurst. Genau dafür hat MS ja diese "isolation" Sache gemacht. Aber deswegen dürfen da doch nicht einfach Zeiger ins Leere zeigen 😕

    Aber egal, ich hab keine Zeit da länger nachzuforschen.

    Was wäre da jetzt angebracht? Allen DLLs und MFC EXEn so ein Manifest verpassen?

    ps: Ich verstehe auch nicht wieso meine DLL und die EXE verschiedene COMCTL32 Versionen verwenden sollten. Die haben nämlich allesamt kein ComCtl-Manifest. Ich hätte mir gedacht wenn allesamt keins haben, sollte das gleich gut sein, wie wenn alle das selben haben ... nicht?


Log in to reply