Мне стало известно, что мой двоичный файл будет зависать на процессоре без поддержки SSE, с кодом исключения 0xC000001D
(STATUS_ILLEGAL_INSTRUCTION), несмотря на то, что я компилирую с параметром /arch:IA32
. И я был в состоянии отследить точное место, где он падает: везде, где _snprintf_s()
вызывается в первый раз, он падает. Сбой внутри ucrtbase.dll , , а не моего собственного кода.
Теперь интересная часть заключается в том, что, когда я делаю "полностью статическую" сборку с опцией компилятора /MT
, чтобы избежать зависимости explicity от ucrtbase. dll , полученный бинарный файл работает просто отлично! Но, как только я скомпилирую точно какой-то код как «разделяемую» сборку с параметром /MD
, он снова вылетит в ucrtbase.dll .
Таким образом, может показаться, что «статическая» версия UCRT все еще может работать на процессоре без поддержки SSE, но «общей» (DLL) ) версия может не . Это несоответствие явно показалось бы мне ошибкой!
Есть мысли?
Среда построения:
- Windows 10 v1803
- Visual Studio 2017.8 (v15.8.1)
- Windows SDK v10.0. 17134 .12
- Набор инструментов:
v141_xp
- Опция компилятора:
/arch:IA32
Испытательная машина (используется только для сравнительного тестирования):
- Процессор: Pentium II
- ОС: Windows XP с пакетом обновления 3
Примечание: Redist DLL (ucrtbase.dll
+ api-ms-win-*.dll
) для настройки «общей» сборки были скопированы прямо из каталога C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x86
! Насколько мне известно, это последняя доступная версия этих библиотек DLL (v10.0.17134.12).
Даже эта минимальная тестовая программа воспроизведет сбой:
#include <stdio.h>
int main()
{
char buffer[128];
_snprintf_s(buffer, 128, _TRUNCATE, "Hello %s!\n", "World!");
fputs(buffer, stdout);
getc(stdin);
return 0;
}