3

Since the installed of a Windows update on 14.9.2017 we have problems creating certain structs in our release builds. I have noticed that compiled code on computers without that update runs as expected ("Wrong start: 1.1.1990..."), on computer with the update in question installed, the code is not working correctly ("Wrong start: 1.1.2000..."). This happens in all versions of the .NET Frameworks starting from version 4.x.

 class Program
    {
        static void Main(string[] args)
        {
            DateTime start1 = new DateTime(1990, 1, 1, 6, 0, 0);
            DateTime end1 = new DateTime(2000, 1, 1, 6, 0, 0);
            var r2 = new DateTimeRange(start1, end1);
            var r3 = new Range<DateTime>(r2.From, r2.To);
            Console.WriteLine($"Wrong start: {r3.From}, correct start: {start1}");
            Console.ReadLine();
        }
    }

   public struct DateTimeRange 
    {
        private Range<DateTime> m_range;

        public DateTimeRange(DateTime from, DateTime to)
        {
            m_range = new Range<DateTime>(from, to);
        }


        public DateTime From
        {
            get { return m_range.From; }
        }

        public DateTime To
        {
            get { return m_range.To; }
        }
    }

    public struct Range<T> where T : struct
    {
        private T m_from;
        private T m_to;


        public Range(T from, T to)
        {
            m_from = from;
            m_to = to;
        }


        public T From
        {
            get { return m_from; }
        }

        public T To
        {
            get { return m_to; }
        }
    }
wp78de
  • 18,207
  • 7
  • 43
  • 71
  • Define "works wrong". What's the symptom/error? – DiskJunky Sep 14 '17 at 16:04
  • Which Windows Updates were installed on that date? – AKX Sep 14 '17 at 16:07
  • Delete bin folder in project and recompile. New Bin folder will be created. The compiler doesn't recognize a dependency on Framework so the compiler will not automatically update all the objects. So deleting the bin will force compiler to fully recompile the project. – jdweng Sep 14 '17 at 16:08
  • Does this affect your debug build as well, and if so, can you debug this to see where the wring date is set? – oerkelens Sep 14 '17 at 16:10
  • It doesn't affect debug build. Wrong behavior means that end1 is propagated to the From property in Range class and therefore r3.From in an example has a year value 2000, instead of 1990 (with different date its also propagated). updates version on Win10 is KB4038782 (probably this update : https://blogs.msdn.microsoft.com/dotnet/2017/09/12/net-framework-september-2017-security-and-quality-rollup/), but it affected all servers and personal computers which installed any update today. – robert guth Sep 14 '17 at 18:10
  • Recompiling is not helping (I deleted bin folder). Every time i build this in release build, it gives me the output with year 2000. In debug build, it gives me output 1990. – robert guth Sep 14 '17 at 18:15
  • Update: when i start new project in visual studio and i paste the code from this post, it works allright. When i switch target framework property to framework 4.0, it starts to be "broken". Since then, switching to newer framework is nor repairing the problem. – robert guth Sep 14 '17 at 18:26

1 Answers1

3

I see it, after rebooting my machine. Definitely quacks like bug in the update. On my machine I see C:\Windows\Microsoft.NET\Framework64\v4.0.30319\corjit.dll, dated 9/6/17, 9:23AM CDT, version 4.7.2110.0.

The bug is specific to the x64 jitter and only occurs in the Release build with the optimizer enabled. It matches the kind of bugs that I've seen in the jitter before, most optimizer bugs in the past were related to code handling structs.

Unfortunately I have a hard time characterizing the bug, the code gen is too beefy and the workaround I found does not seem to make enough difference in the machine code on first glance. But is otherwise the typical way to sail around these kind of optimizer bugs:

using System.Runtime.CompilerServices;
...
    public DateTime From {
        [MethodImpl(MethodImplOptions.NoInlining)]
        get { return m_range.From; }
    }

The other workarounds are forcing 32-bit mode or falling back to the legacy jitter. Please report the bug so they can fix it, let me know if you don't want to take the time and I'll take care of it.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 1
    Thanks for suggestion and help, we reported the problem. Mentioned atribute is working, but we hope it will be solved in general. – robert guth Sep 15 '17 at 08:05