来自 VS C++ 在 Windows 上的非法指令
Illegal instruction from VS C++ on Windows
我有一个C++应用程序,对于某些Windows 7用户来说,它在启动时崩溃。我无法在自己的机器上重现错误,但使用breakpad生成了一个.dmp文件,该文件显示代码因"非法指令"初始化静态std::vector数组而崩溃。这可能意味着什么?
例外:Unhandled exception at 0x000000013F121362 (myApp.exe) in myApp.exe.4328.dmp: 0xC000001D:
Illegal Instruction.myApp.exe! dynamic initializer for Keyboard::key_freqs_() Line 11 C++
不合时宜:
const std::vector<double> Keyboard::key_freqs_ = std::vector<double>({
**Crashed here->** 000000013F121362 vmovaps ymm0,ymmword ptr [__ymm@404059fbe76c8b44403ede353f7ced91403d228f5c28f5c3403b800000000000 (01408B7DE0h)]
000000013F12136A movzx r9d,byte ptr [rsp+20h]
000000013F121370 lea r8,[rbp+1F0h]
000000013F121377 vmovups ymmword ptr [rsp+30h],ymm0
000000013F12137D vmovaps ymm0,ymmword ptr [__ymm@404499fbe76c8b44404371eb851eb85240425a9fbe76c8b4404152f1a9fbe76d (01408B7E00h)]
000000013F121385 vmovups ymmword ptr [rsp+50h],ymm0
000000013F12138B vmovaps ymm0,ymmword ptr [__ymm@4049f4dd2f1a9fbe40487fdf3b645a1d40471fdf3b645a1d4045d3b645a1cac1 (01408B7E20h)]
000000013F121393 vmovups ymmword ptr [rsp+70h],ymm0
000000013F121399 vmovaps ymm0,ymmword ptr [__ymm@405059fbe76c8b44404ede147ae147ae404d22b020c49ba6404b800000000000 (01408B7E40h)]
000000013F1213A1 vmovups ymmword ptr [rbp-70h],ymm0
000000013F1213A6 vmovaps ymm0,ymmword ptr [__ymm@40549a0c49ba5e354053720c49ba5e3540525a9fbe76c8b4405152f1a9fbe76d (01408B7E60h)]
000000013F1213AE vmovups ymmword ptr [rbp-50h],ymm0
000000013F1213B3 vmovaps ymm0,ymmword ptr [__ymm@4059f47ae147ae1440587fef9db22d0e40571fef9db22d0e4055d3a5e353f7cf (01408B7E80h)]
000000013F1213BB vmovups ymmword ptr [rbp-30h],ymm0
000000013F1213C0 vmovaps ymm0,ymmword ptr [__ymm@406059eb851eb852405ede147ae147ae405d228f5c28f5c3405b800000000000 (01408B7EA0h)]
000000013F1213C8 vmovups ymmword ptr [rbp-10h],ymm0
...
编辑:正如答案所暗示的那样,我使用的是/arch:AVX 编译标志,它不适用于所有机器。
vmovups
是一个AVX指令。AVX 从 Intel Sandy Bridge(第 2 代 i3/i5/i7 系列(2xxx 及更高版本(,2011 年左右推出(和 Bulldozer 的 AMD 开始支持 AVX。
在较旧的CPU(或当前的奔腾/赛扬或低功耗Atom/Silvermont(上,指令将捕获非法指令错误。
您应该在没有 AVX 支持的情况下重新编译您的应用和/或使用__cpuid
来检查 CPU 功能,并在需要时将执行委托给"慢速"版本。
虚拟机可能不会通过 AVX 支持,但这是可配置的。 如果来宾操作系统在 CPUID 标志中看不到 AVX,则它不会设置允许 AVX 指令执行而不会出错的控制寄存器位。 (此必须启用机制可防止使用 AVX 的用户空间的状态被无法识别 AVX 的操作系统上的上下文切换损坏。
因此,与BMI2等其他扩展不同,如果真正的硬件支持它们(无论虚拟化CPUID如何(,则可以使用BMI2,而引入新架构状态的扩展则不是这种情况:AVX和AVX-512。
虚拟机可能默认为没有 AVX 的客户机,因此可以将虚拟机迁移到没有 AVX 的主机。
直接的答案是:您已经为 AVX 寄存器和指令进行了编译,并且代码假定 AVX 可用,但某些用户在 AVX 不可用的情况下运行您的代码。
不太直接的是,可能有两种情况。一个是,正如已经告诉您的那样,处理器可能太旧而无法获得AVX支持。另一个,即使对你来说晚了一年,也是我的兴趣,是操作系统可能故意没有启用处理器的AVX功能。
Windows 7对此特别影响。AVX 指令出现故障,除非操作系统已启用 AVX 状态组件以与 XSAVE 一起使用以保存和恢复上下文切换上的 AVX 状态。与FXSAVE相比,AVX是第一个需要XSAVE的功能。因此,如果Microsoft编写其XSAVE支持而不计划AVX,那将是一个历史之谜。XSAVE支持从最初的Windows 7开始。
奇怪的是,最初的Windows 7将启用AVX(如果处理器具有AVX(,但实际上从未启用过。原因是 hwpolicy .sys驱动程序的资源中的策略。最初的Windows 7具有对AVX和XSAVE的操作系统支持,但是将AVX与XSAVE一起使用是被策略禁用的!(我还没有发现这曾经发表过,并不是说我对谷歌很好。
Windows 7 SP1中的策略允许AVX,但仅适用于真正的Intel和AuthenticAMD处理器(这可能是另一回事(。如果您希望在原始Windows 7上启用AVX,可以通过更新策略来获取它!
但请注意:即使对于SP1,系统的AVX支持是否完全正确尚不清楚。当然存在问题,甚至有些问题当时Microsoft承认。Microsoft的用户模式文档到处都有 SP1 要求,但直到今天,内核模式文档都没有提到 SP1。
那么,总结一下,Windows 7,甚至SP1上的AVX都有些麻烦,Microsoft可以说是不太开放。十年后,没有人应该被这抓住。
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- C++中的移动分配出现问题.非法指令: 4.
- while 循环 c++ 中的非法指令
- 来自 VS C++ 在 Windows 上的非法指令
- AVX512 非法指令
- 在Visual "Microsoft studio 2019"上设置OpenCV 4.1.1时遇到问题?(非法指令。
- 在运行基本 Avx512 代码时获取非法指令
- exe_common.inl中的非法指令
- 从C 调用Tensorflow Lite .tflite CNN模型时,非法指令
- _mm_fmadd_pd程序收到信号SIGILL,非法指令
- 仅在64位释放模式中的位移位非法指令
- 程序收到信号Sigill非法指令
- 标准::字符串中的非法指令
- 获取列表的第一个和最后一个元素<string>给我非法指令错误
- 为什么Folloing代码在2010年Visual Studio(X64应用程序)中抛出非法指令例外
- std::p romise::get_future 提出非法指令 (SIGILL)
- 使用mpopcnt编译会导致非法指令错误
- 使用带有自定义对齐分配器实现的最新g++,使用SSE和-O3选项编译时出现非法指令(核心转储)
- 程序接收到信号SIGILL,非法指令
- 在VMWare机器上编译的程序在亚马逊服务器上运行时会因非法指令而崩溃