Sau khi nâng cấp gần đây lên .net 4.6, chúng tôi phát hiện ra lỗi mà RyuJit tạo kết quả không chính xác, chúng tôi có thể giải quyết vấn đề này bằng cách thêm useLegacyJit enabled = "true" vào app.config.RyuJit tạo kết quả không chính xác
Tôi làm cách nào để gỡ lỗi mã máy được tạo bởi những điều sau đây?
Tôi đã tạo một dự án bảng điều khiển mới trong VS 2015 RTM, được đặt thành Phát hành, Mọi CPU, không được chọn Ưu tiên 32 bit, chạy cùng và không kèm theo trình gỡ lỗi tạo ra cùng một kết quả.
using System;
using System.Runtime.CompilerServices;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Calculate());
Console.WriteLine(Calculate());
Console.ReadLine();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Value Calculate()
{
bool? _0 = (bool?)null;
bool? _1 = (bool?)true;
if (!Value.IsPresent<bool>(_1))
{
return default(Value);
}
bool? result = null;
result = (_1.Value ? new bool?(false) : result);
if (_0.HasValue && _0.Value)
{
}
return new Value(result);
}
public struct Value
{
bool? _value;
public Value(bool? value)
{
_value = value;
}
public static bool IsPresent<T>(bool? _)
{
return _.HasValue;
}
public override string ToString()
{
return _value.ToString();
}
}
}
}
Nó nên sản xuất: False False
nhưng thay vào đó nó tạo ra: Đúng False
Phần chính của ví dụ này là
result = true ? false : result;
mà phải luôn luôn trở lại sai, nhưng như bạn có thể thấy từ đầu ra, nó trả về True lần đầu tiên phương thức của anh ta được chạy và một câu trả lời khác vào lần thứ hai phương thức được chạy. Việc loại bỏ một số dòng khác khỏi phương thức Calculate() sẽ làm cho nó trả về True luôn, nhưng ví dụ được đưa ra là gần nhất mà tôi có thể tạo lại cho kịch bản sản xuất thực tế của chúng ta.
Vâng, đó là lỗi tối ưu hóa nội tuyến. Hàm Calculate inlined đầu tiên() có một lệnh xấu. Hình như tôi có một '!' Ở đâu đó bên trong trình tối ưu hóa không nên ở đó. Không có gì chúng tôi có thể làm để sửa lỗi này tất nhiên, bạn có thể báo cáo nó tại connect.microsoft.com. Chỉ cần lay off MethodImplOptions.AggressiveInlining trong một thời gian, đó là dường như không được thử nghiệm rộng rãi. –
Mã sản xuất thực tế không có thuộc tính AggressiveInlining, nhưng đó là cách duy nhất tôi có thể tái tạo hành vi trong ví dụ nhỏ này. Mã sản xuất đang được tạo ra một phần, đó là lý do tại sao mã ví dụ trông hơi lạ. Tôi vừa báo cáo nó tại https://connect.microsoft.com/VisualStudio/feedback/details/1578173 – BrandonAGr
@BrandonAGr Lỗi này gây ra khi nội tuyến? Sử dụng 'MethodImplOptions.NoInlining' là một công việc có thể xung quanh? – Andre