KHẮC PHỤC: Các chương trình được tích hợp trong Visual C++ 2013 gặp sự cố với ngoại lệ "Hướng dẫn Không hợp pháp"

Áp dụng cho
Visual Studio Community 2013

Triệu chứng

Khi bạn xây dựng một chương trình bằng Microsoft Visual C++ 2013, chương trình sẽ gặp sự cố và bạn nhận được một ngoại lệ "Hướng dẫn Không hợp pháp". Điều này xảy ra do một số hàm thư viện toán học dấu phẩy động trong Visual C++ 2013 x64 C Runtime (CRT) không kiểm tra chính xác xem một số hướng dẫn AVX và FMA3 nhất định có sẵn dùng hay không trước khi các hàm tìm cách sử dụng chúng. Nếu không có sẵn các hướng dẫn để sử dụng, thì việc gọi các hàm này sẽ gây ra ngoại lệ chỉ lệnh không hợp lệ (0xc000001d). Các hàm bị ảnh hưởng bao gồm log, log10, pow, và những hàm khác. 

Sự cố này có nhiều khả năng xảy ra nhất trong các kịch bản sau:

  • Trên phiên bản cũ của hệ điều hành Windows không hỗ trợ lưu trạng thái AVX (ví dụ: Windows Vista) nếu trình điều hành này được sử dụng trên máy tính hỗ trợ tập lệnh AVX

  • Nếu lưu trạng thái AVX bị vô hiệu hóa rõ ràng trong cấu hình khởi động hệ điều hành

  • Trong Môi trường Cài đặt sẵn của Windows (Windows PE)

    Lưu ý: Windows PE không hỗ trợ lưu trạng thái AVX.

Sự cố này đã được báo cáo trên Microsoft Connect:

Hàm x64 log() sử dụng lệnh vpsrlq AVX mà không liên quan đến hệ điều hành (vì vậy nó bị lỗi trên Vista x64)
        
         Visual Studio 2013 RTM: Lỗi tạo mã C++ x64 cho hướng dẫn AVX2

Nguyên nhân

Sự cố này xảy ra vì Visual C++ 2013 x64 C Runtime không kiểm tra xem hệ điều hành có hỗ trợ lưu trạng thái AVX hay không trước khi cố gắng chạy lệnh AVX hoặc FMA3.

Giải pháp

Nếu tất cả các nhị phân C++ bị ảnh hưởng được tạo bằng Visual C++ 2013 đều sử dụng C Runtime DLL (msvcr120.dll), hãy cài đặt Microsoft Visual C++ 2013 Redistributable – 12.0.40660.0 hoặc phiên bản mới hơn.

Nếu các nhị phân C++ bị ảnh hưởng của bạn liên kết tĩnh với Visual C++ 2013 C Runtime, bạn phải cập nhật cài đặt Visual Studio 2013 của mình bằng cách cài đặt hotfix 3174417, rồi xây dựng lại và triển khai lại các nhị phân bị ảnh hưởng.

Lưu ý: Sự cố này không ảnh hưởng đến các phiên bản cũ hơn của Visual C++ C Runtime (Visual C++ 2012 và các phiên bản cũ hơn). Sự cố này đã được khắc phục trước khi có bản phát hành đầu tiên của Universal CRT được Visual C++ 2015 sử dụng.

Trung tâm Tải xuống của Microsoft

Để cập nhật Visual C++ 2013 C Runtime được liên kết tĩnh, hotfix 3174417 được phát hành dưới dạng bản cập nhật chỉ tải xuống và không được phân phối qua Windows Update. Thông tin có sẵn tại trang web Trung tâm Tải xuống của Microsoft:

Tải gói xuống ngay bây giờ.

Để cập nhật các DLL Visual C++ 2013 C Runtime được liên kết động, bạn có thể cài đặt bản cập nhật có thể phân phối lại. Để biết thêm thông tin, hãy xem bài viết sau trong Cơ sở Tri thức Microsoft:

Bản cập nhật 3179560 dành cho Gói Visual C++ 2013 và Visual C++ có thể phân phối lại

Giải pháp thay thế

Để khắc phục vấn đề này, hãy tắt FMA3 trong thư viện toán học nếu bạn bị ảnh hưởng bởi vấn đề này. Bạn có thể truy vấn xem hệ thống có hỗ trợ các hướng dẫn AVX hay không bằng cách gọi GetEnabledXStateFeatures và tắt AVX trong CRT một cách rõ ràng bằng cách gọi _set_FMA3_enable(0).

Để biết thêm thông tin, hãy xem Làm việc với Ngữ cảnh XState trên trang web MSDN.

Hàm _set_FMA3_enable(0) được khai báo bằng <math.h> và chỉ khả dụng khi bạn dựng cho x64. (Sự cố này chỉ ảnh hưởng đến các thư viện x64.) Điều này làm cho thư viện toán học quay trở lại sử dụng các triển khai không phải FMA3.