Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explain critical bug in Visual Studio 2010 and up, WinForms and WPF

Try putting the following code inside Load event handler for WinForms or Loaded for WPF.

Dim doc As New XmlDocument
Dim nsmgr As New XmlNamespaceManager(Nothing) 'this line throws an exception

Problem is that exception is not thrown, and stack corruption happens. It may have different side effects, depending on the IDE - see below.

  • Affected IDEs are: 2008, 2010 and 2012 (those I could test). 2010 resets stack state, and returns from sub/handler, like nothing happened (but without proceeding with other statements there). 2012 may warn a user about a failed application and an attempt to run in compatibility mode. Next time after that it runs the same as 2010. 2008 properly throws an exception, but only on default configuration (AnyCPU). Switching platform target to x86 makes the problem reappear in 2008 as well.
  • Affected frameworks are WinForms and WPF. Console apps and ASP.NET seem to work fine. .NET v2.0-4.5.
  • Affected scope is only Load event so far. Putting this code into a button makes it work.
  • Affected build configuration = any. Tried on default Debug and Release.

Why I consider it a bug is because it can leave objects in an unstable state - they did not finish initializing, which is not an expected behavior. What's critical about it is that nobody will know it happened, as it does not throw an exception. Depending on your design, you may end up with incorrect data in your database, which in the worst case may lead to severe consequences.

Does anyone have a good explanation to why this may be happening and if there is a workaround?

like image 623
Neolisk Avatar asked Oct 31 '12 15:10

Neolisk


1 Answers

The problem is caused by the wow64 emulation layer that comes into play when you target x86 platform on a x64 OS.
It swallows exceptions in the code that is responsible to fire the Load event.
Thus the debugger doesn't see the exception and cannot step in to handle the situation.
This article seems to document well what's happening there,

This previous answer from Hans Passant (to which goes all the credits and upvotes) explains possible workarounds.
My preferite one is to move everything out of Form_Load event and put the problematic code in the form constructor. (Of course I don't know if it is applicable in your case)

like image 131
Steve Avatar answered Oct 06 '22 18:10

Steve