Windows上VS C ++的非法指令 [英] Illegal instruction from VS C++ on Windows

查看:124
本文介绍了Windows上VS C ++的非法指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C ++应用程序,对于某些Windows 7用户,该应用程序在启动时崩溃.我无法在自己的计算机上重现该错误,但使用Breakpad生成了一个.dmp文件,该文件显示代码因初始化静态std :: vector数组的非法指令"而崩溃.这可能意味着什么?

I have a C++ application that is crashing on startup for some Windows 7 users. I can't reproduce the error on my own machine, but used breakpad to generate a .dmp file, which shows that the code is crashing with "Illegal instruction" initializing a static std::vector array. What could this possibly mean?

例外: myApp.exe.4328.dmp中0x000000013F121362(myApp.exe)的未处理异常:0xC000001D:

非法的Instruction.myApp.exe!Keyboard :: key_freqs_()Line 11 C ++的动态初始化程序

该行的来源:

const std::vector<double> Keyboard::key_freqs_ = std::vector<double>({
    27.5, 29.135, 30.868, 32.703, 34.648, 36.708, 38.89, 41.203, 43.654, 46.249, 48.999, 51.913,
    55, 58.271, 61.735, 65.406, 69.296, 73.416, 77.782, 82.407, 87.307, 92.499, 97.999, 103.82, 110,
    116.54, 123.47, 130.81, 138.59, 146.83, 155.56, 164.81, 174.61, 185, 196, 207.65, 220, 233.08,
    246.94, 261.63, 277.18, 293.66, 311.13, 329.63, 349.23, 369.99, 392, 415.3, 440, 466.16, 493.88,
    523.25, 554.37, 587.33, 622.25, 659.26, 698.46, 739.99, 783.99, 830.61, 880, 932.33, 987.77,
    1046.5, 1108.7, 1174.7, 1244.5, 1318.5, 1396.9, 1480, 1568, 1661.2, 1760, 1864.6, 1975.5, 2093,
    2217.5, 2349.3, 2489, 2637, 2793.8, 2959.9, 3136, 3322.4, 3520, 3729.3, 3951.1, 4186});

标题:

class Keyboard {
 public:
  static const std::vector<double> key_freqs_;
  ...
};

Disssembly:

Dissasembly:

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  
...

不确定这是否重要,但是在最近的构建中,我开始直接在应用程序文件夹中分发Visual Studio运行时dll,而不是执行vc_redist.exe.

Not sure if this matters, but in the most recent build I started distributing the Visual Studio runtime dlls directly in the application folder instead of executing vc_redist.exe.

推荐答案

vmovups

vmovups is an AVX instruction. AVX is supported starting from Intel Sandy Bridge (2nd gen i3/i5/i7 series (2xxx and later), introduced around 2011), and AMD from Bulldozer.

在较旧的CPU(或当前的Pentium/Celeron或低功率的Atom/Silvermont)上,指令将被捕获,并带有非法指令错误.

On an older CPU (or current Pentium/Celeron or low-power Atom/Silvermont) the instruction will trap with an Illegal Instruction error.

您应该在没有AVX支持的情况下重新编译您的应用程序和/或使用 __ cpuid

You should either recompile your app without AVX support and/or use __cpuid to check the CPU capabilities, and delegate execution to the "slow" version, if needed.

虚拟机在默认情况下可能不会通过AVX支持,但这是可配置的.如果客户机OS在CPUID标志中看不到AVX,则不会设置使AVX指令无故障执行的控制寄存器位.(这种必须启用的机制可以防止使用AVX的用户空间的状态被不支持AVX的OS上的上下文切换破坏.)

Virtual machines may not pass through AVX support by default, but this is configurable. If the guest OS doesn't see AVX in the CPUID flags, it won't set the control-register bit that lets AVX instructions execute without faulting. (This must-enable mechanism prevents AVX-using user-space from having its state corrupted by context switches on an AVX-unaware OS.)

因此,与其他扩展(例如BMI2)不同,如果真正的硬件支持它们,则可以使用它们(与虚拟CPUID无关),而引入新的架构状态的扩展(AVX和AVX-512)就不是这种情况.

So unlike other extensions like BMI2 that you can use if the real HW supports them (regardless of virtualized CPUID), that's not the case for extensions that introduce new architectural state: AVX and AVX-512.

VM可能默认为没有AVX的客户机,因此可以将VM迁移到没有AVX的主机.

VMs may default to a guest without AVX so the VM can be migrated to hosts without AVX.

这篇关于Windows上VS C ++的非法指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆