Сбой в _snprintf_s () в & quot; ucrtbase.dll & quot; с STATUS_ILLEGAL_INSTRUCTION

Мне стало известно, что мой бинарный файл будет зависать на процессоре без Поддержка SSE, с кодом исключения 0xC000001D (STATUS_ILLEGAL_INSTRUCTION), несмотря на то, что я компилирую с опцией /arch:IA32, И я был в состоянии отследить точное место, где он падает _snprintf_s() вызывается впервые, он вылетит. Авария внутри ucrtbase.dll, не мой собственный код

Теперь интересно частично, когда я делаю «полностью статическую» сборку с опцией компилятора /MT, так, чтобы избежать зависимости ucrtbase.dll, полученный бинарный файл работает просто отлично! Но, как только я скомпилирую точно какой-то код как «разделяемую» сборку, с опцией /MD, это снова рухнет в ucrtbase.dll.

Таким образом, казалось бы, что «статическая» версия UCRT еще Можно работа на процессоре без Поддержка SSE, но «общая» (DLL) версия может не. Это несоответствие явно показалось бы мне ошибкой!

Какие-нибудь мысли?


Построить среду:

  • Windows 10 v1803
  • Visual Studio 2017.8 (v15.8.1)
  • Windows SDK v10.0.17134.12
  • Toolset: v141_xp
  • Опция компилятора: /arch:IA32

Тестовая машина (используется только для тестирования):

  • Процессор: Pentium II
  • ОС: Windows XP с пакетом обновления 3

Замечания: 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;
}

2

Решение

Обновить:

После некоторой дополнительной отладки и возни, я сделал очень интересное наблюдение: «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, было бы почти невозможно сделать неправильно …

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]