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