Exception control when release an application? - c#

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.

Related

Your application has stopped working, even when hooking to UnhandledExceptionHandler

I have added a global error handler at the AppDomain level to my C# application, by hooking into the UnhandledExceptionHandler event.
My problem is, that even though i am handling this exception, i still get the popup saying "App has stopped working".
Is this normal behaviour? Can it be turned off? or maybe it is good practice to actually have this message displayed?
Is this normal behaviour?
Yes. Think about it, where should your code be resumed? In what state?
Can it be turned off?
Only by handling exceptions a the appropriate point in your program, ie in the toplevel code. The UnhandledExceptionHandler is not a replacement but a diagnosis-tool for incomplete handling.
or maybe it is good practice to actually have this message displayed?
Yes. You should log exceptions that arrive there but you've already lost control.
I don't think is possible to recover the existing instance of an app when you get at that point. MSDN has no information about it and is suggested " If sufficient information about the state of the application is available, other actions may be undertaken — such as saving program data for later recovery." (link)
It kind of makes sense to not be able to recover. If you catch an exception in the Unhandled ExceptionHandler it means that your application was not able to deal with it so is your last chance to log what happened (for later investigations) or save the user's data. It sounds like an architecture problem if the "unhandled" exception handler must "handle" exceptions and recover the app.
Why not recover by creating a new instance of the app? (or by using the Restart and Recovery feature)

How to catch exceptions from another program (for logging)?

I am working on a tool that monitors a number of applications and ensures they are always running and in a clean state. Some of these applications have unhandled exceptions which do occur periodically and present the 'send crash report' window. I do not have the source code to these applications.
Is there any mechanism I could use to catch the exceptions, or simply identify their exception type, as well as identify the application's main executable file that threw the exception.
I'm not trying to do anything crazy like catch and handle it on the applications behalf, I'm simply trying to capture the exception type, log it and then restart the application.
Trapping unhandled exceptions requires calling SetUnhandledExceptionFilter() in the process. That's going to be difficult to do if you don't have source code, although it is technically possible by injecting a DLL into the process. This however cannot be done with managed code, you can't get the CLR initialized properly.
The default unhandled exception handler that Windows installs will always run WerFault.exe, the Windows Error Reporting tool. That can be turned off but that's a system setting. Expecting your user or admin to do this is not realistic. Only after WER runs will the JIT debugger get a shot at it.
I recommend a simpler approach, one that's also much more selective. Use the Process class to get the program you're interested in protecting started. When the Exited event fires, use the ExitCode property to find out how it terminated. Any negative value is a sure sign that the process died on an unhandled exception, the exit code matches the exception code. You can use the EventLog class to read the event message that WER writes to the Windows event log. And you can restart it the same way you got it started.
Without modifying the source of the application or injecting a DLL into the process I do not believe this is possible in a reliable fashion. What you're attempting to do is inspect type information across a process boundary. This is not easy to achieve for a number of reasons
Getting the name of the exception implies executing code in the target process. The name can be generated a number of ways (.ToString, or .GetType().Name) but all involve executing some method
You want to do this after the application has already crashed and hence may be in a very bad state. Consider trying to execute code if memory was corrupted (perhaps even corrupting the in memory definitions of the type).
The crash could occur in native code and not involve any managed data
If you want to monitor application crashes system wide, you can register yourself as a just-in-time debugger. You can edit the registry to specify which debugger to run when an application crashes. The example they give is Doctor Watson, but it could be your application instead.

Catching an Unhandled Exception Raised by an Unmanaged Sub-Process

Using C#'s System.Diagnostics.Process object, I start an unmanaged exe, that later starts yet another unmanaged exe.
The 2nd exe is causing an unhandled-exception that I'd like my application to ignore, but can't seem to.
I'm using a try/catch statement when I start the first process, but it doesn't seem to catch the exception raised by the 2nd process. When the exception occurs, the just-in-time debugger notifies me and halts my application until I manually click "yes" I want to debug or "no". Then my application proceeds.
The JIT debugger doesn't have source code for the 2ndprocess.exe that is throwing the exception. So, it doesn't tell me what the exception is. I don't really care what the exception is, I just want to know how to catch it and ignore it so my application doesn't get halted by it. By the time the exception occurs, the work is done anyway.
Can anyone offer some insight?
You should be properly handling the exception in the second executable. Your main program won't catch the exception because it isn't throwing one, it is executing something that is.
Edit:
Do you have access to the source of the second process (the one throwing the exception)? Your application shouldn't ever just crash. If the exceptional case gets handled correctly in the second process, you won't have this problem in your primary application.
Edit2:
Since you have access to the source (open source) I recommend you fix the bug. This will help you in two ways:
1) Your program will finally work.
2) You can say you contributed to an open source project.
And, as a special bonus, you get to help out a project you use frequently. Win/Win
Since you are using process.start to actually launch the application, the application creates a separate application domain. Capturing the exception from that application is not something that I believe will be possible, since more than likely the JIT dialog is coming up due to that failed process.
Although not a solution you could stop the dialog if needed, but that has issues of its own.

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

How to identify problem when program crashes without showing error?

Please let me know what steps I need to follow when my application crashes and closes showing the dialog containing "Don't send" and "Send error report" buttons.
What can I possibly do other than looking at the event viewer to solve this?
Thanks
You could add a try/catch/finally construct around your Main() entry method's body.
For WinForms, you can add a ThreadException handler, just before Application.Run(), to catch exceptions thrown in WinForms UI event handlers:
Application.ThreadException +=
new ThreadExceptionEventHandler(Application_ThreadException);
All other unhandled exceptions can be caught using:
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
But it's worth mentioning that this only allows you to log/report the exception - you cannot prevent the application from closing once you exit this final handler.
Visual Studio can also be configured to break on first chance exceptions, and external debuggers (like WinDbg with managed SoS extensions) can catch first-chance exceptions too (http://www.codeproject.com/KB/debug/windbg_part1.aspx).
Also, use a logging framework like log4net to add useful logging to your app and dump exception information before the application closes.
Ask your users if they can reproduce the error and how. If you can reproduce the error, run in debug in Visual Studio and follow the steps to cause the crash. Visual studio will enter debug mode where it catches the error. Form there you will be able to follow the stack trace and see what code is causing the error. Visual studio makes debugging pretty easy most of the time.
Ideally you should use a logging library such as nLog or log4net to log any unhandled exceptions, and exceptions in general, by logging them in your code when they occur.
It can also help to have different levels of logging in your application to help you track down a problem when it's not running on your development machine. With nLog you can leave the logging in your production code and enable / disable log output through the use of a logging config file.
I've not used log4net so I don't know if it has a similar feature.
The "send/don't send" errors tend to happen when you have an unhandled exception in a background thread (the main thread will show that continue/quit .NET dialog with a stack trace).
Add an exception handler to your thread's function and log from there:
void RunMyThread()
{
try
{
// background thread code
}
catch (Exception ex)
{
// Log the exception
}
}
This is highly simplified, and may not be how you want to handle an exception. But hopefully this will get you moving in the right direction.
Use WinDBG to debug the issue. You can make it break (as in stop on a breakpoint) when an exception is thrown, and then examine the stacktrace... objects in scope etc...
If it happens at a customer site, and isn't easily reproducable inside a developers debugger, you could do some post mortem debugging. I like to use Userdump to gather a memory dump file (.DMP). Then I use windbg for analysis.

Categories