我寫了一個創建ATL CString對象的DLL。我使用「Visual Studio 2015 - Windows XP(v140_xp)」平臺工具集對Visual Studio 2015進行編譯。該DLL使用LoadLibrary/GetProcAddress加載。在Windows XP下的CAtlStringMgr :: GetInstance崩潰
在分配字符串對象時,它在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(thread)。
我正在尋找修復/解決方法(除了從VS2015回到VS2013)。
問題已經被報告給微軟,但他們並沒有發表評論/修復尚未:https://connect.microsoft.com/VisualStudio/feedback/details/1635157/crash-in-catlstringmrg-getinstance-under-windows-xp
「threadSafeInit-」應該默認用於使用Windows XP工具集構建的DLL。 – nusi