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.
Related
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.
I've a WPF application which runs globally fine. But sometimes, the client tell me that he gots some crashes. But I've no information about what happened except what he does.
Is there a way to put a global try{}catch(Exception){LOGEXCEPTION; throw;} somewhere to receive all exceptions generated by a GUI action, or any other option.
Something like a "Last remedy" to log exception that we didn't manage well?
Thank you!
By handling the following events, you should be able to catch the vast majority (if not all) unhandled exceptions in your application:
Application.DispatcherUnhandledException
AppDomain.CurrentDomain.UnhandledException
I am running some import code asynchronously from a simple WinForms app using a BackgroundWorker object and its DoAsync() method. I had a problem where I didn't know that exceptions were being thrown and the thread was prematurely dying. I eventually discovered this, and now know when an exception is thrown after reading Unhandled exceptions in BackgroundWorker.
However, I still have a problem while debugging. How do I debug this code? I guess I could run it in a test app that doesn't use a BackgrounWorker, but is there a way to debug this as is? If I step through the code that actually throws the exception, I just get kicked out the step-through when the exception occurs. Re-throwing the exception from the RunWorkerCompletedEventHandler naturally doesn't help much either.
Any ideas!? Thanks in advance!
Why not use "Break On Exceptions" option of VS (Ctrl + Alt + E or Debug->Exceptions and put checkbox in Thrown column)? This will stop your program execution when any exception is thrown.
Visual Studio will only let you step into the code if you have the source. If you don't have the source then I suggest learning how to use winDBG. MS has an excellent tutorial here:
http://blogs.msdn.com/tess/pages/net-debugging-demos-information-and-setup-instructions.aspx
It has a learning curve and takes some time but I have found it to be worth it. I've used this tool to debug A LOT of applications that suddenly crash, hang the CPU, or just perform poorly.
How do I suppress an exception in C#? I do not want to enclose it in a try-catch block with an empty catch block - that would defeat the purpose. I have a custom Application_Error handler/listener that checks for HttpException and I would much rather that run automatically than being prompted by Visual Studio for a HttpException and I would have to click Continue in the IDE.
By suppression, I mean to stop this from happening. when the HttpException occurs in my code, a debug exception dialog opens in Visual Studio and my project pauses. Then when I click Continue my Application_Error is able to handle it. I would like it to automatically continue.
In response to Simon's answer, I do not want exception handling turned off globally.
Two Things:
For production: Use ELMAH. Use ELMAH and any Yellow Screen of Death errors get logged.
For Development and YSOD: See this Stack Overflow question that covers your specific issue:
Catching Exceptions within ASPX and ASCX Pages
You can change which exceptions cause the IDE to break by going to Debug -> Exceptions and turn off the Thrown and User-unhandled options for the relevant exceptions.
So I am sold on the concept of attempting to collect data automatically from a program - i.e., popping up a dialog box that asks the user to send the report when something goes wrong.
I'm working in MS Visual Studio C#.
From an implementation point of view, does it make sense to put a try/catch loop in my main program.cs file, around where the application is run? Like this:
try
{
Application.Run(new myMainForm());
}
catch (Exception ex)
{
//the code to build the report I want to send and to
//pop up the Problem Report form and ask the user to send
}
or does it make sense to put try/catch loops throughout pieces of the code to catch more specific exception types? (I'm thinking not because this is a new application, and putting in more specific exception catches means I have an idea of what's going to go wrong... I don't, which is why the above seems to make sense to me.)
-Adeena
I think you are right, you would not know what's going to go wrong, which is the point.
However, you might as well consider adding a handler to the ThreadException event instead.
The code above will work but there will be scenarios where multi threading might be an issue with such code, since not all code inside your windows forms program will be running in the main Application.Run loop thread.
Here's a sample code from the linked article:
[STAThread]
static void Main()
{
System.Windows.Forms.Application.ThreadException += new ThreadExceptionEventHandler(ReportError);
System.Windows.Forms.Application.Run(new MainForm());
}
private static void ReportError(object sender, ThreadExceptionEventArgs e)
{
using (ReportErrorDialog errorDlg = new ReportErrorDialog(e.Exception))
{
errorDlg.ShowDialog();
}
}
More documentation on MSDN.
On a minor point, using the ThreadException event also allow your main message loop to continue running in case the exception isn't fatal (i.e. fault-tolerance scenarios) whilst the try/catch approach may requires that you restart the main message loop which could cause side effects.
From an implementation point of view, does it make sense to put a try/catch loop in my main program.cs file, around where the application is run?
Sure and always.
You should use Try/Catch-Blocks wherever you do something critical, that might raise an exception.
Therefore you can not really stick to a pattern for that, because you should now, when what exception will be raised. Otherwise these are unhandled exceptions, which let your program crash.
But there are many exceptions, that need not to stop the application entirely, exceptions, that just can be swallowed over, as they are expected and do not critically need the application to stop. Example for that are UnauthorizedAccessExceptions when moving or accessing data with your programm.
You should try to keep you Try/Catch-Blocks as small as needed, as well as to use not too much of them, because of performance.
Some out there use Try/Catch for steering the program's execution. That should entirely be avoided wherever possible, cause raising an Exception is performance killer number 1.
Wrapping a try catch around the whole application will mean the application will exit upon error.
While using a try and catch around each method is hard to maintain.
Best practice is to use specific try catches around units of code that will throw specific exception types such as FormatException and leave the general exception handling to the application level event handlers.
try
{
//Code that could error here
}
catch (FormatException ex)
{
//Code to tell user of their error
//all other errors will be handled
//by the global error handler
}
Experience will tell you the type of things that could go wrong. Over time you will notice your app often throwing say IO exceptions around file access so you may then later catch these and give the user more information.
The global handlers for errors will catch everything else. You use these by hooking up event handlers to the two events System.Windows.Forms.Application.ThreadException (see MSDN) and AppDomain.UnhandledException (see MSDN)
Be aware that Out of Memory exceptions and StackOverflowException may not be caught by any error catching.
If you do want to automatically get stack traces, Microsoft do allow you to submit them via the Error Reporting Services. All you need to do is sign up for a Digital Certificate from VeriSign and register it (for free) with Microsoft.
Microsoft then gives you a login for you to download the mini-dumps from a website, which are submitted when a user clicks "Send Error Report".
Although people can hit "Don't Send", at least it is a Microsoft dialog box and possibly not one that you have to code yourself. It would be running 24/7, you wouldn't have to worry about uptime of your web server AND you can submit workaround details for users AND you can deliver updates via Windows Update.
Information about this service is located in this "Windows Error Reporting: Getting Started" article.
The best approach is to sing up for
AppDomain.UnhandledException and Application.ThreadException In your application's main function. This will allow you to record any unhandled exceptions in your application. Wraping run in a try catch block does not catch every thing.
if you just want to capture crashes, then ignore all errors and let DrWatson generate a minidump for you. Then you can look at that ina debugger (windbg is preferred for minidumps) and it'll show you the line your code went wrong on, and also all the parameters, stack trace, and registers. You can set Drwatson to generate a full dump where you'll get an entire memory core dump to investigate.
I wouldn't recommend putting a try/catch around the entire app unless you want your app to never "crash" in front of the user - it'll always be handled, and probably ignored as there's nothing you can do with the exception at that point.
Sending the minidump to you is another matter though, here's an article, you'll have to do some work to get it sent via email/http/ftp/etc.