Exception getting past Application.ThreadException and AppDomain.CurrentDomain.UnhandledException - c#

I'm having a problem with an application hanging and giving me the default "Please tell Microsoft about this problem" popup, instead of the "unhandled exception" dialog in the application.
In the application code, the Application.ThreadException and AppDomain.CurrentDomain.UnhandledException are both redirected to a method which writes an error log to disk, saves a screenshot to disk, and shows a friendly dialog box.
But when this error occurs, none of those three things happen. All I get is this in the event viewer:
EventType clr20e3, P1 myapp.exe, P2 4.0.0.0, P3 47d794d4, P4 mscorlib, P5 2.0.0.0, P6 471ebc5b, P7 15e5, P8 27, P9 system.argumentoutofrange, P10 NIL
Given that the error only seems to happen after the application has been running for several hours, I wonder if it may be a memory-leak problem. I've searched a bit for "clr20e3" but only managed to find ASP.Net stuff. My application is Windows Forms (.Net 2.0) exe, using quite a few assemblies - in both C# and some unmanaged C++.
I guess that it could also be an error in the error handling method - As some answers suggest, I may try logging at the start of error handler (but given that that is pretty much what I do anyway...).
Any help solving this problem would be much appreciated - whether it is solutions, or suggestions in how to find out what the root cause of the problem is.
UPDATE: The root cause of the original bug was accessing an array with a negative index (that was the system.argumentoutofrange). Why this was not trapped is a bit of a mystery to me, but given than both exceptions were sent to the same handling code, I wonder if there may not have been a condition where (for example) both were invoked and fought over a resource (the log file, for example)?
I managed to prove this much by doing an EventLog.WriteEntry before anything else in the error handling code. Having now added a flag to prevent re-entry in the error handling, I no longer appear to have a problem...

Just shooting in the dark here - is it possible that the ArgumentOutOfRangeException is actually thrown from your exception handler?
Additionally, you didn't say what type of application is in question -- Application.ThreadException only affects WinForms threads, so if this isn't a GUI application it's useless. (See the remarks section in the MSDN documentation)

Have you checked whether the ArgumentOutOfRangeException is thrown from your handler itself? May be worthwhile doing a simple write to the event log or trace at the entry of your exception handler and confirm you're actually hitting it.
Edit: Information to writing to the event log can be found at:
http://support.microsoft.com/kb/307024

Are you calling Application.Run() more than once? This will exhibit the same symptons you describe. You must write a custom ApplicationContext class as a work-around. Just my $0.02 adjusted for inflation.

Related

Exception control when release an application?

Possibly an obvious question to some but couldn't find a duplicate.
I'm packaging the final version of a Windows Forms solution I've been working on and am getting it ready for online distribution. What are the best practices when doing so? We've already had some trouble with packaging the installation file and have run into hurdles to test the program on different PCs, both 32 and 64-bit included.
More specifically, should "throw;" commands be commented out or left in the final release? Would this expose any of the inner workings of the solution itself?
Released application should not crash when exception occurs. You will want to inform the user, something went wrong and log your exception, but you do not want to crash! Informing user should be done in a friendly manner and not just by putting exception.ToString() into the message box.
It is a good practice to add Application.ThreadException or AppDomain.CurrentDomain.UnhandledException handlers to handle all exceptions in your Application. How exactly to do that, is answered in the following thread: Catch Application Exceptions in a Windows Forms Application
However, make sure that your application survives in a usable state, i.e. handle exceptions in a proper way for your application.
I usually add a preprocessor directive for handling exceptions on the application level, since I want them to trow while debugging. For example:
#if !DEBUG
Application.ThreadException += new ThreadExceptionEventHandler(MyHandler);
#endif
It should also be mentioned, that if you have code pieces where you anticipate that Exception might occur, such as network communication error, you should handle those pieces explicitly. What I am saying is, we should not completely forget about exception handling, just because we configured an unhandled exception handler on the application level.
Keep all of your exception handling intact.
Add an event to the starting form in the application, attaching to the Application.UnhandledException event. This will fire if an exception propogates up the stack.
This is the point to inform the user that the application has crashed. Log the error here and then abort gracefully.
Your point about revealing internals, thats up to you to decide. You can obfuscate the source code if you wish, but if you are releasing in Release build mode, and you are not providing the .PDB, then this is the first step.
Ultimately, the DLL / EXE can be decompiled anyway, so its up to you. Debug mode will reveal a lot more than Release mode, but not much more.
Ideally, you should be catching anything that's thrown higher with throw;. Carefully check your code and try to ensure that thrown exceptions are dealt with appropriately. Unhandled exceptions are logged - you can see this information in the Windows Event Viewer. Depending on what details you put in them, unhandled exceptions could give clues as to the inner workings of your application. However, I would suggest that unhandled exceptions are a poor source of information, and that anyone who wanted to know how your application worked could simply disassemble it, unless you've obfuscated it.
Some exceptions cannot be caught by surrounding code with try/catch blocks, so your application should also implement an unhandled exception handler. This gives you the opportunity to show the user an error message and do something with the exception - log it, send it to support, discard it, etc.

Catching Unknown Exceptions With C#

I have an application (written in C# / ClickOnce) which, for the most part, works fine; it has no memory leaks and runs reliably and is stable for days at a time.
However, it also utilises MEF (so plugins/extensions can be dynamically added to the core assembly). Again, this 'works' currently, but if an exception/fatal error occurs in an externally linked assembly/plugin, it will crash the entire application.
After some recent testing, I found that the application had crashed after around 14 hours of [successful] operation.
With that in mind, my question is really two-fold:
a) is it possible to catch any unhanded exception a plugin (or the main application) may throw, so it can at least output info for debugging assistance?
b) I can't be sure if it was the plugin or the main application which failed. Therefore, I cannot think where to start debugging/tracing the issue. How does one go about finding a bug which only occurs after such a long period of time?
Thanks for any input.
As noted in the comments (I guess I should have read those before I started typing up an answer...)
When an application throws an exception that is unhandled, it fires the UnhandledException event just before death and you can subscribe to that in order to log any details that will help you figure out what happened.
See this SO post for an example on how to use it (includes ThreadException).

.Net Windows Service Throws EventType clr20r3 system.data.sqlclient.sql error

I have a .Net/c# 2.0 windows service. The entry point is wrapped in a try catch block that notifies me of problems and allows the service to continue operating normally yet when I look at the server's application event log I see a number of "EventType clr20r3" errors that are causing the service to die unexpectedly. The catch block has a "catch (Exception ex)" and does not rethrow the exception.
Each sql commands is of the type "CommandType.StoredProcedure" and are executed with SqlDataReader's. These sproc calls function correctly 99% of time and have all been thoroughly unit tested, profiled, and QA'd. I additionally wrapped these calls in try catch blocks just to be sure and am still experiencing these unhandled exceptions.
This only in our production environment and cannot be duplicated in our dev or staging environments (even under heavy load).
Why would my error handling not catch this particular error? Is there anyway to capture more detail as to the root cause of the problem?
Here is an example of the event log:
EventType clr20r3, P1 RDC.OrderProcessorService,
P2 1.0.0.0,
P3 4ae6a0d0,
P4 system.data,
P5 2.0.0.0, P6 4889deaf,
P7 2490,
P8 2c,
P9 system.data.sqlclient.sql,
P10 NIL.
Additionally
The Order Processor service terminated unexpectedly.
It has done this 1 time(s).
The following corrective action will be taken in 60000 milliseconds:
Restart the service.
Answer from comments. Glad to have helped. :)
Have you tried adding an
AppDomain.UnhandledException event
handler?
msdn.microsoft.com/en-us/library/…
Pretty much the problem is you have an
unhandled SQL exception somewhere in
your code.
Not necessarily, but without seeing
your code or the libraries you are
using, there is no way to know if the
exception is occuring in a different
thread, in a 3rd party library, etc...
By wiring an
AppDomain.UnhandledException handler,
you should at least by able to log the
exception details and figure out where
your problem point is. Just cast the
EventArg to
((Exception)e.ExceptionObject).Message
and you should at least have a better
idea where your unhandled exception
is.
This error is most likely happening on a thread other than your entry point.
You need to somehow define exception handling for your background threads as well.
If you are using WCF to wrap your service, you have the ability to define how faults and other exceptions are handled. Is this how you're hosting your service?
EDIT: If you aren't spawning anything asynchronously, and it's not a WCF/etc app, try handling AppDomain.UnhandledException and logging the detailed error there.

System.Overflow Exception - int32 is too large or small

I need a little advice.
I've got windows service that runs at night. In my development environment, it runs without exception, but when I running it "installed on other machines", when I come in the morning, I'm welcomed with a System.Overflow exception that says that I've set an int32 to a value that is too large or small.
I've carefully combed the service's c# code, and I have try/catch statements around everything, that should catch any error and write it to a log without completely stopping my service with this overflow exception. But still, it occurs and stops the service.
I'd appreciate any conceptual advice on how to pin point what's causing an error such as this.
The problem with adding try/catch blocks throughout your code is it's easy to miss a place and hence not log the exception. A much more robust approach is to use the value AppDomain.UnhandledException. This will fire for any exception which is not handled within the current AppDomain. You can hook into this to write to your log file and hopefully get a better idea at where the error is coming form
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
...
void OnUnhandledException(object sender, UnhandledExceptionEventArgs e) {
// Log the exception here
}
You must have missed an instance of try/catch or you have an error in your error handler or it would be handled.
In windows you can setup your service to restart if it ends unexpected manner.
First, let me tell you that overflow/underflow can be disabled, by opening project properties, selecting "Build" (from the left menu), and then "Advanced...".
By the way, I do it all the time, because it adds overhead, which I don't want in my scientific applications. Manually, then I control things.
But that does not solve the issues... It just hides the "problem", if it is a problem.
If you only care to check about a zero/non zero condition, somewhere in your code, disabling overflow at project settings solves the problem, because even when an overflow occurs you get a nonzero value, and your service continues without problems.
Also, for WinForms applications:
http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx
And WPF:
http://msdn.microsoft.com/en-us/library/system.windows.application.dispatcherunhandledexception.aspx
To get visibility of exceptions on UI threads, since they're not forwarded to AppDomain.CurrentDomain.UnhandledException.

Handling rude application aborts in .NET

I know I'm opening myself to a royal flaming by even asking this, but I thought I would see if StackOverflow has any solutions to a problem that I'm having...
I have a C# application that is failing at a client site in a way that I am unable to reproduce locally. Unfortunately, it is very difficult (impossible) for me to get any information that at all helps in isolating the source of the problem.
I have in place a rather extensive error monitoring framework which is watching for unhandled exceptions in all the usual places:
Backstop exception handler in threads I control
Application.ThreadException for WinForms exceptions
AppDomain.CurrentDomain.UnhandledException
Which logs detailed information in a place where I have access to them.
This has been very useful in the past to identify issues in production code, but has not been giving me any information at about the current series of issues.
My best guess is that the core issue is one of the "rude" exception types (thread abort, out of memory, stack overflow, access violation, etc.) that are escalating to a rude shutdown that are ripping down the process before I have a chance to see what is going on.
Is there anything that I can be doing to snapshot information as my process is crashing that would be useful? Ideally, I would be able to write out my custom log format, but I would be happy if I could have a reliable way of ensuring that a crash dump is written somewhere.
I was hoping that I could implement class deriving from CriticalFinalizerObject and have it spit a last-chance error log out when it is disposing, but that doesn't seem to be triggered in the StackOverflow scenario which I tested.
I am unable to use Windows Error Reporting and friends due to the lack of a code signing certificate.
I'm not trying to "recover" from arbitrary exceptions, I'm just trying to make a note of what went wrong on the way down.
Any ideas?
You could try creating a minidump file. This is a C++ API, but it should be possible to write a small C++ program that starts your application keeps a handle to the process, waits on the process handle, and then uses the process handle to create a minidump when the application dies.
If you have done what you claim:
Try-Catch on the Application.Run
Unhandled Domain Exceptions
Unhandled Thread Exceptions
Try Catch handlers in all threads
Then you would have caught the exception except perhaps if it is being thrown by a third party or COM component.
You certainly haven't given enough information.
What events does the client say leads up to the exception?
What COM or third party components do you use? (Do you properly instance and reference these components? Do you pass valid arguments to COM function calls?)
Do you make use of any un-managed - un-safe code?
Are you positive that you have all throw-capable calls covered with try-catch?
I'm just saying that no-one can offer you any helpful advice unless you post a heck of lot more information and even at that we probably can only speculate as to the source of you problem.
Have a set of fresh eyes look at your code.
Some errors cannot be caught by logging.
See this similar question for more details:
StackOverflowException in .NET
Here's a link explaining asynchronous exceptions (and why you can't recover from them):
http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=c1898a31-a0aa-40af-871c-7847d98f1641

Categories