Mfc 自从使用VS2017和最新的工具集重新构建程序以来,我现在遇到了访问冲突-在关闭程序时

Mfc 自从使用VS2017和最新的工具集重新构建程序以来,我现在遇到了访问冲突-在关闭程序时,mfc,visual-studio-2017,Mfc,Visual Studio 2017,我刚刚遇到了一个我不知道如何解决的问题。我有一个MDI应用程序,我早在2002年就开始了,从那时起它就一直在运行 在VS2017中,我第一次去重建它(使用最新的工具集),除了关闭程序外,一切似乎都很好。引发了一个异常,它将我带到VS2017 IDE: 这真是令人困惑。堆栈跟踪: > [Inline Frame] CommunityTalks_x64.exe!ATL::CImage::CInitGDIPlus::ReleaseGDIPlus() Line 583 C++ Symbol

我刚刚遇到了一个我不知道如何解决的问题。我有一个MDI应用程序,我早在2002年就开始了,从那时起它就一直在运行

在VS2017中,我第一次去重建它(使用最新的工具集),除了关闭程序外,一切似乎都很好。引发了一个异常,它将我带到VS2017 IDE:

这真是令人困惑。堆栈跟踪:

>   [Inline Frame] CommunityTalks_x64.exe!ATL::CImage::CInitGDIPlus::ReleaseGDIPlus() Line 583  C++ Symbols loaded.
    [Inline Frame] CommunityTalks_x64.exe!ATL::CImage::CInitGDIPlus::{dtor}() Line 555  C++ Symbols loaded.
    CommunityTalks_x64.exe!`ATL::CImage::GetInitGDIPlusInstance'::`2'::`dynamic atexit destructor for 'gdiPlus''()  C++ Symbols loaded.
    CommunityTalks_x64.exe!_execute_onexit_table::__l2::<lambda>() Line 206 C++ Symbols loaded.
    CommunityTalks_x64.exe!__crt_seh_guarded_call<int>::operator()<void <lambda>(void),int <lambda>(void) & __ptr64,void <lambda>(void) >(__acrt_lock_and_call::__l2::void <lambda>(void) && setup, _execute_onexit_table::__l2::int <lambda>(void) & action, __acrt_lock_and_call::__l2::void <lambda>(void) && cleanup) Line 204  C++ Symbols loaded.
    [Inline Frame] CommunityTalks_x64.exe!__acrt_lock_and_call(const __acrt_lock_id) Line 936   C++ Symbols loaded.
    CommunityTalks_x64.exe!_execute_onexit_table(_onexit_table_t * table) Line 231  C++ Symbols loaded.
    CommunityTalks_x64.exe!common_exit::__l2::<lambda>() Line 230   C++ Symbols loaded.
    CommunityTalks_x64.exe!__crt_seh_guarded_call<void>::operator()<void <lambda>(void),void <lambda>(void) & __ptr64,void <lambda>(void) >(__acrt_lock_and_call::__l2::void <lambda>(void) && setup, common_exit::__l2::void <lambda>(void) & action, __acrt_lock_and_call::__l2::void <lambda>(void) && cleanup) Line 224 C++ Symbols loaded.
    [Inline Frame] CommunityTalks_x64.exe!__acrt_lock_and_call(const __acrt_lock_id) Line 936   C++ Symbols loaded.
    CommunityTalks_x64.exe!common_exit(const int return_code, const _crt_exit_cleanup_mode cleanup_mode, const _crt_exit_return_mode return_mode) Line 278  C++ Symbols loaded.
    CommunityTalks_x64.exe!__scrt_common_main_seh() Line 290    C++ Symbols loaded.
    kernel32.dll!00007ffcd5301fe4() Unknown No symbols loaded.
    ntdll.dll!00007ffcd71defb1()    Unknown No symbols loaded.
这不是我的个人密码,我不知道发生了什么。我的输出日志:

The thread 0x2c50 has exited with code 0 (0x0).
'CommunityTalks_x64.exe' (Win32): Unloaded 'C:\Windows\System32\userenv.dll'
'CommunityTalks_x64.exe' (Win32): Unloaded 'C:\Windows\System32\d3d10warp.dll'
Exception thrown at 0x00007FFCD35E3FB8 (KernelBase.dll) in CommunityTalks_x64.exe: 0x0000071A: The remote procedure call was canceled, or if a call time-out was specified, the call timed out.
The thread 0x960 has exited with code 0 (0x0).
The thread 0xd84 has exited with code 0 (0x0).
The thread 0x8dc has exited with code 0 (0x0).
The thread 0x1270 has exited with code 0 (0x0).
The thread 0x33c has exited with code 0 (0x0).
The thread 0x2308 has exited with code 0 (0x0).
The thread 0x53c has exited with code 0 (0x0).
The thread 0x20c0 has exited with code 0 (0x0).
Exception thrown at 0x00007FFCD71BBE6B (ntdll.dll) in CommunityTalks_x64.exe: 0xC0000005: Access violation writing location 0x0000000000000024.

The program '[2204] CommunityTalks_x64.exe' has exited with code 0 (0x0).
我不知道发生了什么,我必须停止调试过程

我深陷其中,不知如何是好

更新 我无意中发现:

更新2 我试图根据注释中的建议放置断点,但异常已经触发。我在这里被引导到一个相关的问题:

其中一种解决办法是:

作为解决方案,请尝试禁用THEADSeaveInIT:Ad/ZC:THeReStuleIn-IT+C++编译器选项)-它应该解决问题。 我刚刚更改了设置,现在没有发生异常。我也向上看了看,但是我的头上全是。我只知道我以前没有问题。除非添加此开关,否则dbeugger始终会导致异常

这有多重要?只做这项工作可以吗

更新3 我关闭了WindowsBlinds,以防它被插入,并在此方法中使用断点进行了调试跟踪:

inline bool CImage::CInitGDIPlus::Init() throw()
有趣的是,这会被截获,仔细检查,这里是堆栈:

    CommunityTalks_x64.exe!ATL::CImage::CInitGDIPlus::Init() Line 573   C++ Symbols loaded.
    [Inline Frame] CommunityTalks_x64.exe!ATL::CImage::InitGDIPlus() Line 2075  C++ Symbols loaded.
    CommunityTalks_x64.exe!ATL::CImage::Load(IStream * pStream) Line 1376   C++ Symbols loaded.
>   CommunityTalks_x64.exe!CPngImage::LoadFromBuffer(unsigned char * lpBuffer, unsigned int uiSize) Line 4057   C++ Symbols loaded.
    CommunityTalks_x64.exe!CPngImage::Load(const wchar_t * lpszResourceName, HINSTANCE__ * hinstRes) Line 3986  C++ Symbols loaded.
    CommunityTalks_x64.exe!CMFCToolBarImages::LoadStr(const wchar_t * lpszResourceName, HINSTANCE__ * hinstRes, int bAdd) Line 942  C++ Symbols loaded.
    CommunityTalks_x64.exe!CMFCRibbonInfoLoader::LoadImageW(const CMFCRibbonInfo::XID & id, CMFCToolBarImages & image, int bSingle) Line 150    C++ Symbols loaded.
    CommunityTalks_x64.exe!CMFCRibbonInfoLoader::LoadImageW(CMFCRibbonInfo::XImage & image, int bSingle) Line 199   C++ Symbols loaded.
    CommunityTalks_x64.exe!CMFCRibbonInfoLoader::LoadFromBuffer(unsigned char * lpBuffer, unsigned int nSize) Line 124  C++ Symbols loaded.
    CommunityTalks_x64.exe!CMFCRibbonInfoLoader::Load(const wchar_t * lpszResID, const wchar_t * lpszResType, HINSTANCE__ * hInstance) Line 88  C++ Symbols loaded.
    CommunityTalks_x64.exe!CMFCRibbonBar::LoadFromResource(const wchar_t * lpszXMLResID, const wchar_t * lpszResType, HINSTANCE__ * hInstance) Line 1146    C++ Symbols loaded.
    CommunityTalks_x64.exe!CMainFrame::OnCreate(tagCREATESTRUCTW * lpCreateStruct) Line 298 C++ Symbols loaded.
    CommunityTalks_x64.exe!CWnd::OnWndMsg(unsigned int message, unsigned __int64 wParam, __int64 lParam, __int64 * pResult) Line 2292   C++ Symbols loaded.
    CommunityTalks_x64.exe!CWnd::WindowProc(unsigned int message, unsigned __int64 wParam, __int64 lParam) Line 2099    C++ Symbols loaded.
    CommunityTalks_x64.exe!AfxCallWndProc(CWnd * pWnd, HWND__ * hWnd, unsigned int nMsg, unsigned __int64 wParam, __int64 lParam) Line 265  C++ Symbols loaded.
    CommunityTalks_x64.exe!AfxWndProc(HWND__ * hWnd, unsigned int nMsg, unsigned __int64 wParam, __int64 lParam) Line 417   C+

+   Symbols loaded.
CMFCToolBarImages::LoadStr
方法具有以下代码位:

// Try to load PNG image first:
CPngImage pngImage;
if (pngImage.Load(lpszResourceName, hinstRes))
{
    hbmp = (HBITMAP) pngImage.Detach();
}
else
此代码
if(pngImage.Load(lpszResourceName,hinstRes))
调用:

BOOL bRes = LoadFromBuffer((LPBYTE) lpBuffer, (UINT) ::SizeofResource(hinstRes, hRsrc));
LoadFromBuffer
调用是这样组成的:

BOOL CPngImage::LoadFromBuffer(LPBYTE lpBuffer, UINT uiSize)
{
    ASSERT(lpBuffer != NULL);

    HGLOBAL hRes = ::GlobalAlloc(GMEM_MOVEABLE, uiSize);
    if (hRes == NULL)
    {
        return FALSE;
    }

    IStream* pStream = NULL;
    LPVOID lpResBuffer = ::GlobalLock(hRes);
    ASSERT (lpResBuffer != NULL);

    memcpy(lpResBuffer, lpBuffer, uiSize);

    HRESULT hResult = ::CreateStreamOnHGlobal(hRes, TRUE, &pStream);

    if (hResult != S_OK)
    {
        return FALSE;
    }

    if (CMFCToolBarImages::m_bMultiThreaded)
    {
        CMFCToolBarImages::m_CriticalSection.Lock();
    }

    if (m_pImage == NULL)
    {
        m_pImage = new CImage;
        ENSURE(m_pImage != NULL);
    }

    m_pImage->Load(pStream);
    pStream->Release();

    BOOL bRes = Attach(m_pImage->Detach());

    if (CMFCToolBarImages::m_bMultiThreaded)
    {
        CMFCToolBarImages::m_CriticalSection.Unlock();
    }

    return bRes;
}
请注意,它有以下代码:

if (m_pImage == NULL)
{
    m_pImage = new CImage;
    ENSURE(m_pImage != NULL);
}
因此,我们有一个
CImage
对象。果不其然:

// Attributes:
protected:
    static ATL::CImage* m_pImage;

它是
CMFCToolBarImages
框架使用的
CPNGImage
类的一部分,而不是我自己在做的事情。如果不添加
threadSafeInit-
标志,当应用程序关闭时,调试器将始终为我崩溃。

我相信threadSafeInit实现了C++11中引入的一个功能,通常称为。显然,这不仅对函数局部静力学的构造有影响,而且对(破坏顺序)也有影响。它是在Visual Studio 2015中引入的,默认情况下处于启用状态。如果您正在移植VS2015之前版本的代码,则禁用该选项与使用VS2015之前版本的编译器编译代码相同。如果代码以前是正确的,它仍然没有启用threadSafeInit选项。我仍然希望看到一个复制此问题的程序,以了解到底发生了什么。显然,
CImage
实现确实使用函数本地静态进行GDI+初始化/取消初始化,因此这可能确实是MFC中的一个bug。为了安全地确定这一点,必须隔离问题。虽然像
CImage
这样的常用类出现缺陷听起来有点不合理。看起来他们已经修复了它:谢谢你的工作!刚刚被这个问题深深地折磨了一下,你让我开心极了!我可以确认
/Zc:threadSafeInit-
解决了这个问题。再次感谢您的工作,/Zc:threadSafeInit-也在这里为我工作。在我的例子中,它将基于MFC功能区的应用程序从VS2015移植到VS2017。我还为你之前链接的MS问题添加了一个帖子,因为他们认为这个问题在最新的更新中已经解决了,但我不认为已经解决了。看见
// Attributes:
protected:
    static ATL::CImage* m_pImage;