xp动态库中使用CString遇到的异常错误CAtlStringMrg::GetInstance

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.

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

Here is the disassembly:

    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]

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.

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

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

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

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

解决方案

Thanks to David to point me in the right direction. Here's the workaround:

Properties -> C/C++ -> Command Line -> add "/Zc:threadSafeInit-"

Related documents:

https://connect.microsoft.com/VisualStudio/feedback/details/1715018/dll-usage-of-thread-safe-magic-statics-may-crash-on-windows-xp

Access violation on static initialization

https://connect.microsoft.com/VisualStudio/feedback/details/1789709/visual-c-2015-runtime-broken-on-windows-server-2003-c-11-magic-statics

https://msdn.microsoft.com/en-us/library/vstudio/hh567368.aspx

本文地址:IT屋 » Crash in CAtlStringMgr::GetInstance under Windows XP

问 题

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



在分配字符串对象时,在CAtlStringMrg :: GetInstance中,它在Windows XP下崩溃。



这是反汇编:



 

code> 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

***是导致崩溃的指令。 eax和ecx为零。 ***
1003B10D mov esi,dword ptr [eax + ecx * 4]


你可以看到代码引用__tls_index,因此它使用线程本地存储。 dumpbin也显示了一个.tls部分,当我用旧的Visual Studio 2013编译我的项目时不存在。



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



但是,我不知道为什么使用线程本地存储。我找不到__declspec(线程)在ATL源的任何地方。



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



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


解决方案

感谢David指向正确的方向。以下是解决方法:



属性 - > C / C ++ - >命令行 - >添加“/ Zc:threadSafeInit - ” 

相关文件:



https://connect.microsoft.com/VisualStudio/feedback/details/1715018/ dll-usage-of-thread-safe-magic-statics-may-crash-on-windows-xp



<a href="http://www.it1352.com/%E2%80%9Chttp%EF%BC%9A" stackoverflow.com="" questions="" 32517234="" access-violation-on-static-initialization\"="" style="box-sizing: border-box; color: rgb(24, 188, 156); text-decoration: none; background-color: transparent;">静态初始化存取违规



https ://connect.microsoft.com/VisualStudio/feedback/details/1789709/visual-c-2015-runtime-broken-on-windows-server-2003-c-11-magic-statics



https:// msdn。 microsoft.com/en-us/library/vstudio/hh567368.aspx


本文地址:IT屋 » 在Windows XP下崩溃在CAtlStringMgr :: GetInstance

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值