Я написал DLL, которая создает объект ATL CString. Я скомпилирую его с помощью Visual Studio 2015 с помощью набора инструментов платформы Visual Studio 2015 - Windows XP (v140_xp). DLL загружается с использованием LoadLibrary/GetProcAddress.Ошибка в CAtlStringMgr :: GetInstance под Windows XP
Сбой при использовании 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.
Локальное хранилище нитей не поддерживается в Windows XP при динамической загрузке DLL. Это объясняет, почему сбой кода выше.
Однако я не мог понять, почему используется локальное хранилище потоков. Я не могу найти __declspec (нить) в любом месте источников ATL.
Я ищу исправление/обходное решение (кроме возврата от VS2015 к VS2013).
вопрос уже сообщалось в Microsoft, но они не стали комментировать/исправить еще: https://connect.microsoft.com/VisualStudio/feedback/details/1635157/crash-in-catlstringmrg-getinstance-under-windows-xp
«threadSafeInit-» должен быть установлен по умолчанию для сборки DLL с помощью набора инструментов Windows XP. – nusi