35

最近 .net 4.6 にアップグレードした後、RyuJit が誤った結果を生成するバグを発見しました。現在、useLegacyJit enabled="true" を app.config に追加することで、この問題を回避することができました。

以下によって生成されたマシンコードをデバッグするにはどうすればよいですか?

VS 2015 RTM で新しいコンソール プロジェクトを作成し、Release、Any CPU に設定し、Prefer 32 ビットのチェックを外し、デバッガーを接続して実行しても、接続せずに実行しても同じ結果が得られます。

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();
            }
        }
    }
}

以下を生成する必要があります: False False

しかし、代わりに以下を生成します: True False

この例の重要な部分は

result = true ? false : result;

これは常に false を返す必要がありますが、出力からわかるように、メソッドが最初に実行されると True が返され、メソッドが 2 回目に実行されると別の答えが返されます。Calculate() メソッドからさらにいくつかの行を削除すると、常に True が返されますが、示されている例は、実際の運用シナリオに最も近いものです。

4

1 に答える 1