我注意到我的二进制文件将在没有SSE 支持的情况下在 CPU 上崩溃,并带有异常代码0xC000001D
(STATUS_ILLEGAL_INSTRUCTION),尽管我正在使用 option 进行编译/arch:IA32
。而且我已经能够追踪到它崩溃的确切位置:无论_snprintf_s()
第一次调用哪里,它都会崩溃。崩溃在ucrtbase.dll内部,而不是我自己的代码。
现在,有趣的是,当我使用编译器选项进行“完全静态”构建时,为了避免对ucrtbase.dll/MT
的显式依赖,生成的二进制文件就可以了!但是,一旦我将某些代码编译为“共享”构建,使用 option ,它将在 ucrtbase.dll中再次崩溃。/MD
所以看起来UCRT的“静态”版本仍然可以在没有SSE支持的CPU上工作,但“共享”(DLL)版本不能。这种不一致对我来说显然是一个错误!
有什么想法吗?
搭建环境:
- 视窗 10 v1803
- Visual Studio 2017.8 (v15.8.1)
- Windows SDK v10.0。17134 .12
- 工具集:
v141_xp
- 编译器选项:
/arch:IA32
测试机(仅用于兼容性测试):
- CPU:奔腾II
- 操作系统:带有 Service-Pack 3 的 Windows XP
注意:用于设置“共享”构建的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;
}