Мне стало известно, что мой бинарный файл будет зависать на процессоре без Поддержка SSE, с кодом исключения 0xC000001D
(STATUS_ILLEGAL_INSTRUCTION), несмотря на то, что я компилирую с опцией /arch:IA32
, И я был в состоянии отследить точное место, где он падает _snprintf_s()
вызывается впервые, он вылетит. Авария внутри ucrtbase.dll, не мой собственный код
Теперь интересно частично, когда я делаю «полностью статическую» сборку с опцией компилятора /MT
, так, чтобы избежать зависимости ucrtbase.dll, полученный бинарный файл работает просто отлично! Но, как только я скомпилирую точно какой-то код как «разделяемую» сборку, с опцией /MD
, это снова рухнет в ucrtbase.dll.
Таким образом, казалось бы, что «статическая» версия UCRT еще Можно работа на процессоре без Поддержка SSE, но «общая» (DLL) версия может не. Это несоответствие явно показалось бы мне ошибкой!
Какие-нибудь мысли?
Построить среду:
v141_xp
/arch:IA32
Тестовая машина (используется только для тестирования):
Замечания: Redist DLLs (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;
}
Обновить:
После некоторой дополнительной отладки и возни, я сделал очень интересное наблюдение: «Redist» библиотеки UCRT, содержащиеся в самый последний vcredist_x86.exe
(Распространяемый установщик Microsoft Visual C ++ 2017), то есть версия, которая поставляется с VS2017.8 (v14.15.26706), на самом деле сильно отличается от тех «Redist» DLL UCRT, которые можно найти в Redist\ucrt\DLLs\x86
каталог самый последний Windows SDK (V10.0.17134.12):
ucrtbase.dll
от самый последний Windows SDK
v10.0.17134.12
ucrtbase.dll
от самый последний Распространяемый установщик Visual C ++ 2017:
v10.0.10586.15
Действительно, теперь я могу подтвердить, что приложение, скомпилированное с самый последний Visual C ++ 2017 (версия 14.15.26706) и использование /MD
Опция работает правильно на не-Процессор SSE, пока мы используем «старый» ucrtbase.dll
версия, как извлечено из самый последний vcredist_x86.exe
Установщик.
Я немного обеспокоен использованием такой старой версии UCRT, если Windows SDK уже предоставляет гораздо более новую версию. Но, по всей видимости, именно этим и занимается Microsoft с помощью распространяемого установщика Visual C ++ 2017. Итак, я думаю, это то, что мы должны использовать …
На всякий случай, кто-нибудь в Microsoft читает это:
Вещи могли быть путь менее запутанным и подверженным ошибкам для разработчиков программного обеспечения, если в Redist\ucrt
В каталоге Windows SDK были отдельные подпапки для каждого «воплощения» UCRT — последняя «передовая» версия UCRT и «совместимая» версия UCRT, которую мы фактически должны распространять. Если затем кто-то в Microsoft потратил три минуты на написание небольшого файла README, в котором говорится, какое «воплощение» CRT мы должны выбрать и поместить в Redist\ucrt\README.txt
, было бы почти невозможно сделать неправильно …
Других решений пока нет …