2015-07-22 13 views
35

Nachdem wir kürzlich auf .net 4.6 aktualisiert haben, haben wir einen Fehler entdeckt, bei dem RyuJit falsche Ergebnisse liefert. Wir konnten das Problem jetzt umgehen, indem wir in der app.config useLegacyJit enabled = "true" hinzufügen.RyuJit produziert falsche Ergebnisse

Wie kann ich den Maschinencode debuggen, der durch folgende generiert wird?

Ich habe ein neues Konsolen-Projekt in VS 2015 RTM erstellt, auf Release, Any CPU gesetzt, nicht aktiviert 32-Bit-Vorlauf, läuft mit und ohne Debugger angeschlossen erzeugt das gleiche Ergebnis.

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

sollten Sie folgendes Ergebnis: Falsch Falsch

sondern es produziert: Wahr Falsch

Der wichtigste Teil des Beispiels ist

result = true ? false : result; 

Welche sollte immer Rückkehr falsch, aber wie Sie aus der Ausgabe sehen können, gibt es True beim ersten Mal t Die Methode wird ausgeführt, und beim zweiten Mal wird die Methode ausgeführt. Wenn Sie einige weitere Zeilen aus der Calculate() -Methode entfernen, wird immer "True" zurückgegeben, aber das angegebene Beispiel ist das, was ich meinem tatsächlichen Produktionsszenario am nächsten bringen könnte.

+5

Ja, es ist ein Inline-Optimierungsfehler. Die erste inline Calculate() hat eine schlechte Anweisung. Sieht für mich aus, dass irgendwo im Optimierer ein '!' Steht, das nicht da sein sollte. Nichts, was wir tun können, um diesen Fehler zu beheben, können Sie natürlich unter connect.microsoft.com melden. Legen Sie das MethodImplOptions.AggressiveInlining für eine Weile weg, das ist wahrscheinlich nicht ausgiebig getestet worden. –

+0

Der tatsächliche Produktionscode verfügt nicht über das AggressiveInlining-Attribut, aber das ist die einzige Möglichkeit, das Verhalten in diesem kleinen Beispiel zu reproduzieren. Der Produktionscode wird teilweise maschinell erzeugt, weshalb der Beispielcode etwas merkwürdig aussieht. Ich habe es gerade gemeldet unter https://connect.microsoft.com/VisualStudio/feedback/details/1578173 – BrandonAGr

+0

@BrandonAGr Dieser Fehler wird beim Inlining verursacht? Die Verwendung von 'MethodImplOptions.NoInlining' ist eine mögliche Umgehung? – Andre

Antwort

27

Vielen Dank für das isolierte Repro-Programm und ich kann bestätigen, dass dies in der Tat ein RyuJIT-Fehler im Optimierer ist, der durch Inlining ausgesetzt wurde. Ich habe den Compiler repariert und die Rollout-Details ermittelt. Nicht, um SO zu einem Bug-Tracker zu machen und für einen schnelleren Turnaround: [email protected]

+3

Ich habe eine vereinfachte Version des Quellcodes erstellt, Sie finden es im corelclr Repo: https : //github.com/dotnet/coreclr/issues/1299 – AndreyAkinshin

+1

@HansPassant Yeah wollte das nicht als Fehlerbericht, die Art von versteckter Frage war, wie man den ausgeführten Maschinencode findet. Das vereinfachte Beispiel, das Andrey produziert hat, machte es sehr einfach, die Disassemblierung im Visual Studio zu betrachten, natürlich ist es immer noch nicht einfach zu erkennen, welche Register das halten, aber ich konnte es durchlaufen – BrandonAGr

+0

@schellap Setzt das auch fix - https : //connect.microsoft.com/VisualStudio/Feedback/Details/1602437? –

Verwandte Themen