Dopo l'aggiornamento a .net 4.6 abbiamo scoperto un bug in cui RyuJit produce risultati errati, per il momento siamo stati in grado di aggirare il problema aggiungendo useLegacyJit enabled = "true" a app.config.RyuJit produce risultati errati
Come è possibile eseguire il debug del codice macchina generato da quanto segue?
Ho creato un nuovo progetto di console in VS 2015 RTM, impostato su Rilascio, Qualsiasi CPU, deselezionato Prefer 32 bit, in esecuzione con e senza debugger collegato produce lo stesso risultato.
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();
}
}
}
}
Dovrebbe produrre: False Falso
ma invece produce: Vero Falso
La parte fondamentale dell'esempio è
result = true ? false : result;
che dovrebbe sempre ritorno falso, ma come puoi vedere dall'output, restituisce True la prima volta t Il metodo viene eseguito e una risposta diversa la seconda volta che viene eseguito il metodo. Rimuovendo alcune righe dal metodo Calculate(), verrà restituito True sempre, ma l'esempio dato è il più vicino che potrei riprodurre nel nostro scenario di produzione reale.
Sì, si tratta di un bug di ottimizzazione inlining. Il primo Calculate inline() ha una cattiva istruzione. Mi sembra che ci sia un '!' Da qualche parte all'interno dell'ottimizzatore che non dovrebbe essere lì. Nulla di ciò che possiamo fare per correggere questo bug, è possibile segnalarlo su connect.microsoft.com. Basta licenziare MethodImplOptions.AggressiveInlining per un po ', è improbabile che sia stato ampiamente testato. –
Il codice di produzione effettivo non ha l'attributo AggressiveInlining, ma questo è l'unico modo in cui è possibile riprodurre il comportamento in questo piccolo esempio. Il codice di produzione è stato parzialmente generato dalla macchina, motivo per cui il codice di esempio sembra un po 'strano. L'ho appena segnalato su https://connect.microsoft.com/VisualStudio/feedback/details/1578173 – BrandonAGr
@BrandonAGr Questo bug è causato durante l'inlining? Usare 'MethodImplOptions.NoInlining' è un possibile aggiramento? – Andre