使用STATUS_ILLEGAL_INSTRUCTION

时间:2018-08-26 11:34:44

标签: c++ visual-c++ visual-studio-2017 universal-crt

提醒我,尽管我使用选项{{1进行编译,但我的二进制文件将在没有SSE支持的情况下在CPU 上崩溃,异常代码为0xC000001D(STATUS_ILLEGAL_INSTRUCTION)。 }}。而且我已经能够找到崩溃的确切位置:第一次调用 /arch:IA32 时,它将崩溃。崩溃位于 ucrtbase.dll 内部,不是我自己的代码。

现在,有趣部分是,当我使用编译器选项 _snprintf_s() 进行“完全静态”构建时,请避免显式依赖< strong> ucrtbase.dll ,生成的二进制文件就可以了!但是,一旦我将完全相同的代码编译为“共享”构建,并使用选项 /MT ,它将再次在 ucrtbase.dll 中崩溃。 >

因此,似乎 UCRT 的“静态”版本仍然可以 在CPU 上运行而无需 SSE支持,但“共享” “(DLL)版本可以 不能 。这种不一致在我看来显然是个错误!

有什么想法吗?


构建环境:

  • Windows 10 v1803
  • Visual Studio 2017.8(v15.8.1)
  • Windows SDK v10.0。 17134 .12
  • 工具集:/MD
  • 编译器选项:v141_xp

测试机(仅用于兼容性测试):

  • CPU:奔腾II
  • 操作系统:Windows XP Service Pack 3

注意:用于设置“共享”版本的Redist DLL(/arch:IA32 + ucrtbase.dll)已直接从api-ms-win-*.dll目录中复制!据我所知,这是这些DLL的最新可用版本(v10.0.17134.12)。


即使这个最小的测试程序也可以重现崩溃:

C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x86

1 个答案:

答案 0 :(得分:2)

更新

经过更多的调试和摆弄之后,我做了一个非常有趣的观察:最新 vcredist_x86.exe 中包含的UCRT“ Redist” DLL(Microsoft Visual C ++ 2017 Redistributable安装程序),即VS2017.8(v14.15.26706)附带的版本,实际上与 latest的Redist\ucrt\DLLs\x86目录中的UCRT“ Redist” DLLs完全不同。 Windows SDK (v10.0.17134.12):

    最新 Windows SDK中的
  • ucrtbase.dll
    v10.0.17134.12

  • 最新 Visual C ++ 2017可再发行组件安装程序中的
  • ucrtbase.dll
    v10.0.10586.15

实际上,我现在可以确认使用 latest Visual C ++ 2017(v14.15.26706)和 /MD 选项编译的应用程序可以在 -SSE CPU,只要我们使用从最新 提取的“旧” ucrtbase.dll 版本vcredist_x86.exe 安装程序。

如果Windows SDK已经提供了较新的版本,我会担心使用UCRT的旧版本。但是,显然,这就是Microsoft使用Visual C ++ 2017 Redistributable安装程序进行的工作。所以,我想这就是我们应该使用的...


以防万一Microsoft的任何人正在阅读以下内容:

如果在Windows SDK的Redist\ucrt目录中存在单独的内容,则对于软件开发人员来说,事情可能会 更少混乱和容易出错UCRT每个“化身”的子文件夹-UCRT的最新“最先进”版本和我们实际上应该重新分发的UCRT的“兼容”版本。如果 then 微软公司的某人花了三分钟来编写一个小的README文件,该文件告诉我们应该将CRT的哪一个“化身”放入Redist\ucrt\README.txt,则几乎不可能做错了...