Windows XP 下 CAtlStringMgr::GetInstance 崩溃

问题描述:

我编写了一个 DLL 来创建一个 ATL CString 对象.我使用Visual Studio 2015 - Windows XP (v140_xp)"平台工具集在 Visual Studio 2015 中编译它.DLL 是使用 LoadLibrary/GetProcAddress 加载的.

I've written a DLL that creates an ATL CString object. I compile it with Visual Studio 2015 using the "Visual Studio 2015 - Windows XP (v140_xp)" platform toolset. The DLL is loaded using LoadLibrary/GetProcAddress.

它在 Windows XP 下在 CAtlStringMrg::GetInstance 中分配字符串对象时崩溃.相同的应用程序在 Windows Vista 及更高版本上运行良好.

It crashes under Windows XP in CAtlStringMrg::GetInstance when allocating the string object. The same application works well on Windows Vista and later.

拆解如下:

    static IAtlStringMgr* GetInstance()
    {
#pragma warning(push)
#pragma warning(disable: 4640)
        static CWin32Heap strHeap( ::GetProcessHeap() );
1003B100 mov         eax,dword ptr fs:[0000002Ch] 
1003B106 mov         ecx,dword ptr [__tls_index (101B46C8h)] 
1003B10C push        esi 

*** This is the instruction that causes the crash. eax and ecx are zero. ***
1003B10D mov         esi,dword ptr [eax+ecx*4]

如您所见,代码引用了 __tls_index,因此它使用线程本地存储.dumpbin 还显示了一个 .tls 部分,当我使用旧的 Visual Studio 2013 编译我的项目时该部分不存在.

As you can see the code references __tls_index, thus it uses thread local storage. dumpbin also shows a .tls section that is not present when I compile my project with the old Visual Studio 2013.

当动态加载 DLL 时,Windows XP 不支持线程本地存储.这就解释了为什么上面的代码会崩溃.

Thread local storage is not supported on Windows XP when a DLL is loaded dynamically. This explains why the code above crashes.

但是,我无法弄清楚为什么使用线程本地存储.我在 ATL 源代码中的任何地方都找不到 __declspec(thread).

However, I could not figure out why thread local storage is used. I can't find __declspec(thread) anywhere in the ATL sources.

我正在寻找修复/解决方法(除了从 VS2015 返回到 VS2013).

I'm looking for a fix/workaround (other than going back from VS2015 to VS2013).

这个问题已经报告给微软,但他们还没有评论/修复它:https://connect.microsoft.com/VisualStudio/feedback/details/1635157/crash-in-catlstringmrg-getinstance-under-windows-xp

The issue has already been reported to Microsoft, but they did not comment/fix it yet: https://connect.microsoft.com/VisualStudio/feedback/details/1635157/crash-in-catlstringmrg-getinstance-under-windows-xp