在Windows XP下,CAtlStringMgr::GetInstance崩溃

6
我已经编写了一个创建ATL CString对象的DLL。我使用“Visual Studio 2015 - Windows XP(v140_xp)”平台工具集进行编译。该DLL使用LoadLibrary / GetProcAddress进行加载。在Windows XP下,当分配字符串对象时,它会在CAtlStringMrg :: GetInstance中崩溃。相同的应用程序在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(thread)的任何信息。
我正在寻找修复/解决方法(除了从VS2015回退到VS2013之外)。
该问题已经报告给Microsoft,但他们尚未发表评论/修复:https://connect.microsoft.com/VisualStudio/feedback/details/1635157/crash-in-catlstringmrg-getinstance-under-windows-xp
1个回答

6

3
使用Windows XP工具集构建的DLL应该将"threadSafeInit-"设置为默认值。 - nusi
哦,哇,非常感谢!它太难懂了,但好像很容易绕过去...(至少感谢微软提供的这种方法)。 - feos
connect.microsoft.com的链接现在已经失效。关于Windows XP的建议已在Zc threadSafeInit官方文档中说明。 - Кое Кто

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接