try/catch not working inside UnhandledException handler - c#

I've got a weird symptom in an application, where try/catches inside the handler for UnhandledExceptions don't work: (that is a breakpoint inside the catch does not get hit, even if the breakpoint inside the try does).
Obviously searching for 'exception unhandled inside UnhandledException' is not working very well for me.
I've tried doing a mini proof-of-concept, and unfortunately that one works.
So while I'm trying to track down the root of the problem, if anyone here has any ideas where to look I'd be greatful.
(We recently changed from XP to Windows7, and .Net 4.5 from 4.0 - I'm pretty certain that previously this worked).
EDIT: Looks like it's provoked by a call down to a (managed) C++ library which is throwing a System.AccessViolationException. Strangely, if I replace the call with a throw new AccessViolationException, it does do what I want...

You wrote, "We recently changed ... .Net 4.5 from 4.0 - I'm pretty certain that previously this worked." but the following seems worth adding, because pretty sure really means not certain :-)
I read somewhere that AccessViolationException cannot occur in managed code, but may be trapped by the runtime for unmanaged code. Maybe the C++ library calls into unmanaged code?
In .NET 4+ the process will terminate after AccessViolationException. Your exception handler will be ignored. This is among a group of exception types considered unrecoverable: Corrupted State Exceptions. In .NET 4+ you will need to customise the app config to override this behaviour.

Be sure that you try to catch System.AccessViolationException and not native Access Violation error.
When you do throw new AccessViolationException it throws System.AccAccessViolationException.
If library that you calls is native it can throw native Access Violation error, but .NET catch block normally can catch only managed exceptions.

try this:
i think we can't handle Unhandeled exception and have to exit application in finally.
http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx

Related

Catching fatal exceptions thrown from unmanaged code

Currently, there is no way (at least I did not find a way) to catch fatal exceptions (such as Stack Overflow, Segfault, ..) with try-catch block.
I already started issue at .net core repository so for more details you can read there (https://github.com/dotnet/core/issues/4228)
What I'm trying to do is to make the application not crash when there is any segfault/stack overflow/any fatal exception in loaded unmanaged code. what happens now is that .NET CLR kills my application if any fatal error occurs.
Example:
In c# managed code loaded external c++ dll via kernel LoadLibrary function.
Assume the dll is intentionally created for robustness testing therefore when a specific function is called it triggers segfault (e.g. trying to get data from outside of array bounds).
When this error happens this gets caught by .net CLR and immediately kills the calling managed c# code(application).
What I would like is just report that this happens instead of dying silently.
I did some research and found out there is the reasoning behind that which is described in the issue above.

Intentionally cause a fatal exception

I need to create a fatal exception on demand, using C#. While I have done this unintentionally enough times, now I need to, I can't find a simple way.
It's easy enough to cause a null reference error or divide by zero etc., but I need something which will CTD without giving the option to continue.
Thanks for your help.
Don't use an exception to accomplish this, it has too many side-effects. Including not terminating the program at all, whether an unhandled exception ends the program is a CLR policy that can be changed. Both by a custom CLR host and still exposed today by the legacyUnhandledExceptionPolicy config attribute.
The most reliable way to instantly abort a program, without any events getting fired and without any cleanup (including not running finalizers) is Environment.FailFast().
IMHO I prefer a milder approach. I create a custom Exception that I call FatalException. https://learn.microsoft.com/en-us/dotnet/standard/exceptions/how-to-create-user-defined-exceptions. That way when I call methods that throw FatalException, I simply do a try-catch around the call and catch (FatalException fe). I usually re-throw as necessary to get back to parent form which also has a the final catch for the FatalException exception and then log it (I use Log4Net), show a messagebox as to the reason for the Fatal situation and call my overridden Dispose() method and exit the application gracefully. Obviously this becomes more difficult the deeper your nested calls. The extra work is worth the extra grace to me. If this becomes a standard in your application, you will understand it when you encounter it and ensure that you don't break it. I put my Custom Exceptions in a DLL library. If your code is in a library, this approach still works because the Exceptions are also in a library they can be shared by both another library and the main application. This means your library can throw a FatalException as well, although the reasons for doing so should be few a far between.

Microsoft Visual C++ Runtime Library Exception in c#

I am using a fingerprint capture device in my c# application, this device has c# wrapper class for a c++ SDK dll.
Sometimes i get a c++ exception message (see image) and then the application close, the problem is that I can't catch this exception and can't keep application running after this exception.
The Question is: How Can I Catch This Exception in C#?
How Can I Catch This Exception in C#?
You cannot. An unmanaged C++ exception cannot be caught by managed code. You need to catch unmanaged exceptions in unmanaged code. You cannot let unmanaged exceptions propagate outside the unmanaged module.
However, the error dialog suggests that you have a more serious problem. One that cannot be dealt with simply by catching an exception. You will need to work out why your program is terminating the runtime in this catastrophic way, and stop that happening. That error dialog suggests that your program is calling abort(), which is terminal.
In other words you need to prevent this error from happening in the first place, rather than attempting to recover from it. This is not an error that you can hope to recover from.

Finally Block Not Running?

Ok this is kind of a weird issue and I am hoping someone can shed some light. I have the following code:
static void Main(string[] args)
{
try
{
Console.WriteLine("in try");
throw new EncoderFallbackException();
}
catch (Exception)
{
Console.WriteLine("in Catch");
throw new AbandonedMutexException();
}
finally
{
Console.WriteLine("in Finally");
Console.ReadLine();
}
}
NOW when I compile this to target 3.5(2.0 CLR) it will pop up a window saying "XXX has stopped working". If I now click on the Cancel button it will run the finally, AND if I wait until it is done looking and click on the Close Program button it will also run the finally.
Now what is interesting and confusing is IF I do the same thing compiled against 4.0 Clicking on the Cancel button will run the finally block and clicking on the Close Program button will not.
My question is: Why does the finally run on 2.0 and not on 4.0 when hitting the Close Program button? What are the repercussions of this?
EDIT: I am running this from a command prompt in release mode(built in release mode) on windows 7 32 bit. Error Message: First Result below is running on 3.5 hitting close after windows looks for issue, second is when I run it on 4.0 and do the same thing.
I am able to reproduce the behavior now (I didn't get the exact steps from your question when I was reading it the first time).
One difference I can observe is in the way that the .NET runtime handles the unhandled exception. The CLR 2.0 runs a helper called Microsoft .NET Error Reporting Shim (dw20.exe) whereas the CLR 4.0 starts Windows Error Reporting (WerFault.exe).
I assume that the two have different behavior with respect to terminating the crashing process. WerFault.exe obviously kills the .NET process immediately whereas the .NET Error Reporting Shim somehow closes the application so that the finally block still is executed.
Also have a look at the Event Viewer: WerFault logs an application error notifying that the crashed process was terminated:
Application: ConsoleApplication1.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Threading.AbandonedMutexException
Stack:
at Program.Main(System.String[])
dw20.exe however only logs an information item with event id 1001 to the Event Log and does not terminate the process.
Think about how awful that situation is: something unexpected has happened that no one ever wrote code to handle. Is the right thing to do in that situation to run even more code, that was probably also not built to handle this situation? Possibly not. Often the right thing to do here is to not attempt to run the finally blocks because doing so will make a bad situation even worse. You already know the process is going down; put it out of its misery immediately.
In a scenario where an unhandled exception is going to take down the process, anything can happen. It is implementation-defined what happens in this case: whether the error is reported to Windows error reporting, whether a debugger starts up, and so on. The CLR is perfectly within its rights to attempt to run finally blocks, and is also perfectly within its rights to fail fast. In this scenario all bets are off; different implementations can choose to do different things.
All my knowledge on this subject is taken from this article here: http://msdn.microsoft.com/en-us/magazine/cc793966.aspx - please note it is written for .NET 2.0 but I have a feeling it makes sense for what we were experiencing in this case (more than "because it decided to" anyways)
Quick "I dont have time to read that article" answer (although you should, it's a really good one):
The solution to the problem (if you absolutly HAVE to have your finally blocks run) would be to a) put in a global error handler or b) force .NET to always run finally blocks and do things the way it did (arguably the wrong way) in .NET 1.1 - Place the following in your app.config:
<legacyUnhandledExceptionPolicy enabled="1">
The reason for it:
When an exception is thrown in .NET it starts walking back through the stack looking for exception handlers and when it finds one it then does a second walk back through the stack running finally blocks before running the content of the catch. If it does not find a catch then this second walk never happens thus the finally blocks are never run here which is why a global exception handler will always run finally clauses as the CLR will run them when it finds the catch, NOT when it runs it (which I belive means even if you do a catch/throw your finally blocks will still get run).
The reason the app.config fix works is because for .NET 1.0 and 1.1 the CLR had a global catch in it which would swallow Exceptions before they went unmanaged which would, being a catch of course, trigger the finally blocks to run. Of course there is no way the framework can know enough about said Exception to handle it, take for example a stack overflow, so this is probably the wrong way of doing it.
The next bit is where it gets a bit sticky, and I am making assumptions based off of what the article says here.
If you are in .NET 2.0+ without the legacy exception handling on then your Exception would fall out into the Windows exception handling system (SEH) which seems pretty darn similar to the CLR one, in that it walks back through frames until it fails to find a catch and then calls a series of events called the Unhandled Exception Filter (UEF). This is an event you can subscribe to, but it can only have ONE thing subscribed to it at a time, so when something does subscribe Windows hands it the address of the callback that was there before, allowing you to set up a chain of UEF handlers - BUT THEY DON'T HAVE TO HONOR that address, they should call the address themselves, but if one breaks the chain, bap, you get no more error handling. I assume that this is what is happening when you cancel windows error reporting, it breaks the UEF chain which means that the application is shut down immediately and the finally blocks are not run, however if you let it run to the end and close it, it will call the next UEF in the chain. .NET will have registerd one which is what the AppDomain.UnhandledException is called from (thus even this event is not guaranteed) which I assume is also where you get your finally blocks called from - as I can't see how if you never transition back into the CLR a managed finally block can run (the article does not go into this bit.)
I believe this has something to do with changes to how the debugger is attached.
From the .NET Framework 4 Migration Issues document:
You are no longer notified when the debugger fails to start, or when there is no registered debugger that should be started.
What happens is that you choose to start the debugger, but you cancel it. I believe this falls under this category and the application just stops because of this.
Ran this in both release and debug, in both framework 3.5 and 4.0, I see "in Finally" in all instances, yes running it from command line, went as far as closing my vs sessions, maybe it's something on your machine or as Kobi pointed out, maybe platform related (I'm on Win7 x64)

c# finalizer throwing exception?

Quote from MSDN:
If Finalize or an override of Finalize throws an exception, the runtime ignores the exception, terminates that Finalize method, and continues the finalization process.
Yet if I have:
~Person()
{
throw new Exception("meh");
}
then it results in a runtime exception?
p.s. I know that this should never happen, however I'm just curious around this behaviour. One of our clients had an empty try catch around all of their finalizers.. it didn't even log when things went wrong or reserect the object :/
Linking the source of your quote is important. I have to assume it talks about an old version of .NET, perhaps version 1.x. It tried to be "tolerant" of unhandled exceptions, swallowing them without a squeak. That did not work out well, chunks of code silently failing is extraordinarily hard to debug.
The .NET 2.0 version put an end to that, the default CLR host terminates the app for any unhandled exception. An exception in a finalizer is fatal.
I'm curious as to what happens in xamarin since i've seen this happen in production and the android app did not crash, it is possible that a lock occurred on the finalizer thread and the app ran sub-par until restart.

Categories

Resources