c++assemblyvisual-c++avxillegal-instruction

Illegal instruction from VS C++ on Windows


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?

Exception: 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++

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

Edit: As the answers allude to, I was using an /arch:AVX compile flag, which doesn't work on all machines.


Solution

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

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

    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.


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

    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.

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