在Windows XP下崩溃CAtlStringMgr :: GetInstance

时间:2015-09-17 14:50:50

标签: c++ windows-xp visual-studio-2005 atl c-strings

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

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

这是反汇编:

    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编译项目时,该部分不存在。

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

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

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

此问题已经向Microsoft报告,但他们尚未对此进行评论/修复:https://connect.microsoft.com/VisualStudio/feedback/details/1635157/crash-in-catlstringmrg-getinstance-under-windows-xp