Why you shouldn’t upgrade to .NET 4.6 yet

For many .NET is an essential tool, providing language interoperability across numerous programming languages. Programs that have been written for .NET Framework execute in the Common Language Runtime (CLR) software environment, this application virtual machine provides services such as security, memory management, and exception handling. FCL and CLR together constitute .NET Framework.

In July Microsoft rolled out their latest iteration of .NET, announcing that:

With the .NET Framework 4.6, you’ll enjoy better performance with the new 64-bit “RyuJIT” JIT and high DPI support for WPF and Windows Forms. ASP.NET provides HTTP/2 support when running on Windows 10 and has more async task-returning APIs. There are also major updates in Visual Studio 2015 for .NET developers, many of which are built on top of the new Roslyn compiler framework. The .NET languages — C# 6, F# 4, VB 14 — have been updated, too.

We’re also announcing updates to .NET Core and ASP.NET 5, both recently released as beta 5 and included in Visual Studio 2015. The .NET tools for Windows 10 UWP app development, including .NET Native, will be shipping shortly, on 7/29. We will have a lot to share about .NET UWP apps and the .NET Native technology at that time.

However, going beyond the corporate hype that inevitably surrounds these launches, there may be some cause to not update just yet, as a number of experts have warned there appears to be a major bug in the .NET runtime which may crash production applications.

Nick Craver, who is a software developer and system administrator for Stack Exchange, which is the host of the well regarded programming support site Stack Overflow recently posted about his concerns regarding .NET 4.6, explaining that, “The methods you call can get different parameter values than you passed in.”

Craver goes on to state that the bug was not that easy to detect early on as it only appears when the optimisations are enabled in the software, which means that there is no problems when you are building the application and running it in Visual Studio. The bug arises when you go to compile the production build. Attaching a debugger to the build, explains Craver, changes its behaviour and will generally hide the issue. The reason that the team at Stack Overflow spotted it was due to the fact that the heavily exercised HTTP caching code was not working with the new runtime, with a number of unpredictable results occurring.

Writing on GitHub, Craver labelled his report on the issue, “Tail Call bug in RyuJIT incorrect parameters passed, and providing a code that replicates the problem. In the GitHub report it is explained that “When the parameters you’re passing aren’t the ones the method is getting, all sanity goes out the window. What if your method says how much stock to buy? What if it gives dosing information to a patient? What if it tells a plane what altitude to climb to?”

As can be gleaned from the GitHub title, the problem seems to be coming from the new JIT compiler that is called RyuJIT. What appears to be happening is that when optimisation is enabled the last method in the call stack may have a random value passed onto it. As Craver explains, there is an “issue in the .Net 4.6 RTM RyuJIT implementation that incorrectly hooks up parameters during some tail call optimizations. The net result of this is that tail call methods can get the wrong parameters passed… The net result for us is that items are getting cached for drastically shorter durations, or not at all (null often gets passed). On Stack Overflow this causes unpredictable local HTTP cache usage and more hits and heavier load to anything populating it. This is a production blocker on deployment for us, and (we believe) should be for anyone else.”

While still standing behind the release, Microsoft’s .NET Program Manager Rich Lander has responded to the issue by stating that “The team is taking this very seriously. We’re going to talk about it later today as folks get into the office”. Because the issue is in the JIT complier, the only way to avoid this bug is by not updating to .NET 4.6. If you have or do end up installing it before the bug is fixed, even applications that target previous versions of the software could be effected, as the same compiler is used by all of them. While the version that has been bundled with Windows 10 has, according to Craver, has ‘fixed the bug internally’ it has not done so ‘for users,’ meaning that if the problem is as bad as has been stated then Microsoft should be rolling out a comprehensive patch in the near future.

Craver is wonderfully candid in his justification for bringing this issue to light, explaining that “This bug is critical, I am posting the issue for several reasons: We’re not jerks; To raise awareness; To prevent as many people as possible from deploying affected code; To usher a fix and deployment from Microsoft as soon as possible”.

So the take home is that you should avoid updating to .NET 4.6 for the time being, which also means not upgrading to Windows 10. The Microsoft team will be taking this seriously and they should have a patch coming soon so in the mean time just keep working with your older version.

Leave a Reply