Vs2010 Does Not Show Unhandled Exception Message in a Winforms Application on a 64-Bit Version of Windows

VS2010 does not show unhandled exception message in a WinForms Application on a 64-bit version of Windows

This is a nasty problem induced by the wow64 emulation layer that allows 32-bit code to run on the 64-bit version of Windows 7. It swallows exceptions in the code that runs in response to a notification generated by the 64-bit window manager, like the Load event. Preventing the debugger from seeing it and stepping in. This problem is hard to fix, the Windows and DevDiv groups at Microsoft are pointing fingers back and forth. DevDiv can't do anything about it, Windows thinks it is the correct and documented behavior, mysterious as that sounds.

It is certainly documented but just about nobody understands the consequences or thinks it is reasonable behavior. Especially not when the window procedure is hidden from view of course, like it is in any project that uses wrapper classes to hide the window plumbing. Like any Winforms, WPF or MFC app. Underlying issue is Microsoft could not figure out how to flow exceptions from 32-bit code back to the 64-bit code that triggered the notification back to 32-bit code that tries to handle or debug the exception.

It is only a problem with a debugger attached, your code will bomb as usual without one.

Project > Properties > Build tab > Platform target = AnyCPU and untick Prefer 32-bit. Your app will now run as a 64-bit process, eliminating the wow64 failure mode. Some consequences, it disables Edit + Continue for VS versions prior to VS2013 and might not always be possible when you have a dependency on 32-bit code.

Other possible workarounds:

  • Debug > Exceptions > tick the Thrown box for CLR exceptions to force the debugger to stop at the line of code that throws the exception.
  • Write try/catch in the Load event handler and failfast in the catch block.
  • Use Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException) in the Main() method so that the exception trap in the message loop isn't disabled in debug mode. This however makes all unhandled exceptions hard to debug, the ThreadException event is pretty useless.
  • Consider if your code really belongs in the Load event handler. It is very rare to need it, it is however very popular in VB.NET and a swan song because it is the default event and a double-click trivially adds the event handler. You only ever really need Load when you are interested in the actual window size after user preferences and autoscaling is applied. Everything else belongs in the constructor.
  • Update to Windows 8 or later, they have this wow64 problem solved.

Inside Try/Catch, Visual Studio breaks and ends app on Unhandled exception

This question has many moving parts, not sure I can do justice to all of them. Starting point is that you should not subscribe those events if you use a debugger. Wrap that code with If Not System.Diagnostics.Debugger.IsAttached Then so you can properly diagnose and repair unhandled exceptions.

A significant randomizer is what will happen with exceptions that are thrown in a Load event handler. Microsoft had a great deal of trouble properly handling exceptions that are raised while a Windows callback is active. Such as the one that causes the Load event to fire. They changed the rules at Vista, again at Win7, again at Win8. They are different if you run the 32-bit of the 64-bit version. And whether your program runs as a 32-bit or 64-bit process. Using a debugger alters the behavior. The Program Compatibility Assistant may appear when the exception occurs, asking you if you want your program to be "compatible". Everybody says Yes of course, a very bad idea. Adding them up, you can get one of thirty-two different outcomes. Ouch.

It is formally described in this MSDN article but nobody understands it. Not until it doesn't do what they hope for, covered in a question like this one. Mitigating circumstance is that this only bytes when you debug an app, the normal exception back-stop in the message loop ensures this doesn't get out of hand on your user's machine. In other words, what you see when you press Ctrl+F5 or run the program with Explorer is the way you can expect it to work.

This is a problem that affects any GUI program on Windows. But it has a knack of being especially troublesome in a Winforms app, programmers use the Load event entirely too much. Deluded into it by it being the default event for the Form class, it takes but a double-click to generate it. Especially so in VB.NET, it doesn't automatically create the constructor for a form and Visual Basic has a legacy of using the Load event to initialize a form, goes back to VB6.

I normally avoid judging programming practices I see, but using the Load event is today a really rather bad practice because of these problems. Always favor the constructor to initialize a class, a rule that any .NET programmer knows, it isn't different for the Form class. There are exceedingly few reasons to have to use Load, covered in this post.

What does Visual Studio 2010 debugger do with the XmlException in XmlReader.Read?

I think I understand your confusion. When you debug and visual studio handles exception it stops at error line. In normal situation pressing F5 run again the same line and you are in loop of errors. But in your case you have only one exception and then VS run as nothing happened.

I think you realize now what is happening. First attempt on reader.Read() read file for xml data and move index in stream to the end of file. After you pressing F5 you run this line again and reader.Read() return false because EOF. That's it.

In normal run (without debugging) your application die on first uncatched error and nothing else is happening.

Bonus sample as a proof (paste is instead of your while loop):

try
{
while (reader.Read()) { }
}
catch (Exception)
{
Console.Out.WriteLine("We have excpetion, this is wrong file");
}

while (reader.Read()) { } // we have eof so we don't get exception only false

Exceptions thrown in the `OnLoad` method are ignored?

It's because of the Exceptions option in your VS. If you look in the Output window, you should see there is a message printed like this A first chance exception of type 'System.InvalidOperationException' occurred in...

To enable the throwing exception, you can go to Debug -> Exceptions -> Common Language Runtime Exceptions, then you can expand the namespaces and find the exception you want, in your case it's System.InvalidOperationException. Then check the Thrown in the Thrown column.

Sample Image

VS2010 does not show unhandled exception message in a WinForms Application on a 64-bit version of Windows

This is a nasty problem induced by the wow64 emulation layer that allows 32-bit code to run on the 64-bit version of Windows 7. It swallows exceptions in the code that runs in response to a notification generated by the 64-bit window manager, like the Load event. Preventing the debugger from seeing it and stepping in. This problem is hard to fix, the Windows and DevDiv groups at Microsoft are pointing fingers back and forth. DevDiv can't do anything about it, Windows thinks it is the correct and documented behavior, mysterious as that sounds.

It is certainly documented but just about nobody understands the consequences or thinks it is reasonable behavior. Especially not when the window procedure is hidden from view of course, like it is in any project that uses wrapper classes to hide the window plumbing. Like any Winforms, WPF or MFC app. Underlying issue is Microsoft could not figure out how to flow exceptions from 32-bit code back to the 64-bit code that triggered the notification back to 32-bit code that tries to handle or debug the exception.

It is only a problem with a debugger attached, your code will bomb as usual without one.

Project > Properties > Build tab > Platform target = AnyCPU and untick Prefer 32-bit. Your app will now run as a 64-bit process, eliminating the wow64 failure mode. Some consequences, it disables Edit + Continue for VS versions prior to VS2013 and might not always be possible when you have a dependency on 32-bit code.

Other possible workarounds:

  • Debug > Exceptions > tick the Thrown box for CLR exceptions to force the debugger to stop at the line of code that throws the exception.
  • Write try/catch in the Load event handler and failfast in the catch block.
  • Use Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException) in the Main() method so that the exception trap in the message loop isn't disabled in debug mode. This however makes all unhandled exceptions hard to debug, the ThreadException event is pretty useless.
  • Consider if your code really belongs in the Load event handler. It is very rare to need it, it is however very popular in VB.NET and a swan song because it is the default event and a double-click trivially adds the event handler. You only ever really need Load when you are interested in the actual window size after user preferences and autoscaling is applied. Everything else belongs in the constructor.
  • Update to Windows 8 or later, they have this wow64 problem solved.

VS2010 does not show unhandled exception message in a WinForms Application on a 64-bit version of Windows

This is a nasty problem induced by the wow64 emulation layer that allows 32-bit code to run on the 64-bit version of Windows 7. It swallows exceptions in the code that runs in response to a notification generated by the 64-bit window manager, like the Load event. Preventing the debugger from seeing it and stepping in. This problem is hard to fix, the Windows and DevDiv groups at Microsoft are pointing fingers back and forth. DevDiv can't do anything about it, Windows thinks it is the correct and documented behavior, mysterious as that sounds.

It is certainly documented but just about nobody understands the consequences or thinks it is reasonable behavior. Especially not when the window procedure is hidden from view of course, like it is in any project that uses wrapper classes to hide the window plumbing. Like any Winforms, WPF or MFC app. Underlying issue is Microsoft could not figure out how to flow exceptions from 32-bit code back to the 64-bit code that triggered the notification back to 32-bit code that tries to handle or debug the exception.

It is only a problem with a debugger attached, your code will bomb as usual without one.

Project > Properties > Build tab > Platform target = AnyCPU and untick Prefer 32-bit. Your app will now run as a 64-bit process, eliminating the wow64 failure mode. Some consequences, it disables Edit + Continue for VS versions prior to VS2013 and might not always be possible when you have a dependency on 32-bit code.

Other possible workarounds:

  • Debug > Exceptions > tick the Thrown box for CLR exceptions to force the debugger to stop at the line of code that throws the exception.
  • Write try/catch in the Load event handler and failfast in the catch block.
  • Use Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException) in the Main() method so that the exception trap in the message loop isn't disabled in debug mode. This however makes all unhandled exceptions hard to debug, the ThreadException event is pretty useless.
  • Consider if your code really belongs in the Load event handler. It is very rare to need it, it is however very popular in VB.NET and a swan song because it is the default event and a double-click trivially adds the event handler. You only ever really need Load when you are interested in the actual window size after user preferences and autoscaling is applied. Everything else belongs in the constructor.
  • Update to Windows 8 or later, they have this wow64 problem solved.

How can I get WinForms to stop silently ignoring unhandled exceptions?

In your Program.cs' Main function you should also ensure that you've wrapped your call to open the form in a try/catch. Additionally use the AppDomain.UnhandledException to catch exceptions. We also add Application.ThreadException too.

I believe the following will give you hooks into all the exceptions that can be thrown...

static void Main()
{
try
{
System.Windows.Forms.Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
System.Windows.Forms.Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(OnGuiUnhandedException);
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;

var form = new MainForm();
form.ShowDialog();
}
catch (Exception e)
{
HandleUnhandledException(e);
}
finally
{
// Do stuff
}
}

private static void HandleUnhandledException(Object o)
{
// TODO: Log it!
Exception e = o as Exception;

if (e != null)
{

}
}

private static void OnUnhandledException(Object sender, UnhandledExceptionEventArgs e)
{
HandleUnhandledException(e.ExceptionObject);
}

private static void OnGuiUnhandedException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
HandleUnhandledException(e.Exception);
}


Related Topics



Leave a reply



Submit