c# debugging windows crash - c#

I have an app, and after about 20 minutes of idle time the program just crashes. ("Windows has encountered an error and needs to close...")
I have no idea why this is happening. What is the best way to go about debugging something like this?

Generally crashes in .Net applications are caused by an unhandled exception - i.e. an exception in a thread in that application that was not caught in a try-catch block of some sort:
try
{
// Some code that may throw an exception
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
A good first place to check for information about this exception is the application event log, often however you will find that the .Net framework posts only minimal information about the crash - if this is the case then you need to catch and handle the exception yourself, recording enough information to allow you to diagnose the error.
Typically there are two way that you might do this:
1. Ensure that the code for each thread of your application is contained in a try-catch block.
This is the easiest method - unless your application has multiple user threads (you will know if it has), this simply requires that you place a try-catch block around the entry point of your application, for example in a Windows Forms application:
// Probably found somewhere in Program.cs
[STAThread]
static void Main()
{
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
If you are working on a console application then you will need to use something other than MessageBox (see the first example).
If you spawn multiple threads then the entry point method for each thread should also catch all exceptions in a similar way.
2. Handle the UnhandledException event of the current App Domain
This event will be fired whenever any thread throws an unhandled exception in the current App Domain. Generally speaking it is best to use the first method instead, however this event is still useful in some situations.
Example:
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
// The rest of your application
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine(e.ExceptionObject.ToString());
}
Of course it is worth pointing out that the error still might not be caught by either of the above two methods (which is possible if the error is caused by a native module loaded in the same process), however this should probably do the trick.
Finally - Good luck!

Related

Getting exception that caused program to crash without being in debug mode

I have an application in C# that I want to run by just running the .exe from my desktop. However, I'm pretty sure there will be some type of error that will make the program crash. Is there a way to write the problem that caused the program to crash to a text file, so that I can see what caused the issue when users are using the program? I know I can use debug mode to do this but I want to run the application as a stand alone not inside of VS.
Thanks,
I am aware of the try catch blocks and I am already using those where problems might occur. But I am speaking in general. For example if I wasn't sure where the problem would occur. There is no way to print this specific error to a file.
You can try the global try/catch method except that if there is an exception on a background thread it won't be caught. You can use AppDomain.UnhandledException if you want to be notified of any unhandled exception in the appdomain (msdn). You would signup in main before the rest of your program executes like so:
static void Main(string[] args)
{
AppDomain.UnhandledException += WriteUnhandledExceptionToFile;
// rest of program
}
static void WriteUnhandledExceptionToFile(object sender, UnhandledExceptionEventArgs args)
{
// write to where ever you can get it.
string path = Path.Combine(Environment.CurrentDirectory, "UnhandledException.txt");
File.WriteAllText(path, args.ExceptionObject.ToString()); // will print message and full stack trace.
}
Edit
Note that by default Windows Forms and WPF catch any exceptions that are thrown on the UI thread. You will have to subscribe to the Application.ThreadException event (forms) or Application.DispatcherUnhandledException event (wpf) to be notified of exceptions on those threads. The code would be very similar to the code above for the AppDomain event.
Have a global exception handler that writes the exception details to a file.
If you wrap the code in your Main method in a try{}catch{} block, you can write out the exception details in the catch block.
try
{
// Calls to application code
}
catch(Exception ex)
{
// log `ex.ToString()`
throw; // rethrow to ensure termination optionally: `Application.Exit`
}
Even if you aren't logging the problem, you can usually get the error in question from the event viewer within windows.
The first thing you want to look at is the try/catch construct in C#. This is probably your first building block to handling errors.
As for how you handle the errors, that's entirely up to you. Currently your only stated goal is to log them to a file. You can get a lot of details out of the Exception object that you catch and you can write those details to a file. Additionally, you can use logging libraries to help with that sort of thing.
Proper error handling is something of a big subject, really. One thing to keep in mind is logically where you want to catch the exception. Ideally, you want to catch it where you can handle it. That is, where your code can sufficiently recover from the error. If it's a fatal error and the application should stop entirely, then you can throw the exception further up the stack and let it go unhandled (though still logged where you caught it).
If, however, you're in a logical condition where you can just log the error and move on, then the catch block allows you to do just that. Log the details, update the state of any objects/data which need to be updated, and continue with the flow of the application.
you can surround your one of the starting method with try catch block
try
{
///Your code
}
catch(Exception exception)
{
System.IO.File.WriteAllLines("ErrLog.txt", exception.Message);
}
As a permanent solution you can create extension method ToLog and use it whenever you want.
public static void ToLog(this Exception Exception)
{
using (var file = File.AppendText("ErrorLog.txt"))
{
file.WriteLine(DateTime.Now + " : " + exception.Message);
}
}
You can use it in catch block like this
catch(Exception exception)
{
exception.ToLog();
}
See initial information here http://www.csharp-examples.net/catching-unhandled-exceptions/
static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message, "Unhandled Thread Exception");
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled UI Exception");
}
The UnhandledException event handles uncaught exceptions thrown from the main UI thread. The ThreadException event handles uncaught exceptions thrown from non-UI threads.
I would replace the MessageBox with some actual logging (log4net or others). This would give you the ability to log out the errors to another server for distributed applications, file system for local users, event logs, options are fairly unlimited if you're willing to put in the time.

Global try catch

I know try catch have been discussed a lot but I haven’t found a solution to my problem yet.
I’m writing a Silverlight application where every exception should generate a MessageBox that says something like “Sorry of the inconvenience”.
Since I cannot guarantee that my code will be free from exceptions my coworker has instructed me to have a try catch in every method (a couple of hundred) like this:
public void Method1()
{
try
{
...
}
catch (Exception e)
{
MessageBox.Show("Something went wrong, we apologize for the inconvenience. \n" + e.Message);
}
}
public void Method2()
{
try
{
...
}
catch (Exception e)
{
MessageBox.Show("Something went wrong, we apologize for the inconvenience. \n" + e.Message);
}
}
But it seems so excessive. I’ve read that one does not use try catch in this way plus there will be a lot of duplicated code plus the code will be obfuscated and hard to read.
Are there any alternatives like a global try catch I can use?
you can always handle the AppDomain.UnhandledException Event
Try-catches in each and single method is silly. But:
What is the reason your colleague wants you to catch exceptions to that extent? Do you let exceptions slip through to a level where they are unwanted?
I had a similar case with a product already in use with our customers. It was a WPF project that is similar to silverlight. My job was to ride out bugs in old bad code, that nobody still working with us mastered. The application cross-function with other programs in windows and it was impossible to foresee what could go wrong in different environments.
I had these problems:
The program stopped working because of uncaught exceptions.
It was hard to understand what went wrong, in order to fix the bugs. Our customers normally report errors by emailing screen dumps where it was hard to see what happened.
My approach was:
Catching exceptions on selected "user and system end points". That is typically event handlers for button click, drag-n-drop, navigation commands, and so on from the user side, and typically windows messages and server responses from the system side.
A class OopsBox to make the unexpected error handling a one-liner in each catch. Each catch has an as friendly message as possible, and hides the dirty stuff behind an expand button. The box is also used for error messages for expected errors, and in those cases there is no expand button and no dirty stuff to display as we know what went wrong already.
We gained this:
Users had an easier time figuring out a workaround, as they were not thrown out of context, in cases when the error were not severe.
It was, and still is, easier to grasp what went wrong when some unexpected behaviour was reported.
The Oops boxes started out in large frequencies but I believe the product is stabilizing faster now, and the Oops-boxes are much rarer.
Still to this day, when something goes wrong at a customer's, I get the call stack from them in an email. :)
It cost this:
A large walk-through of all the user and system end points.
Some logic had to be re-written to be able to put the catches at the right places.
Summary
Exceptions should be caught before they do any damage, like throwing the user out of context, and in a level where it makes sense.
When users run your program and something unexpected happens, make sure you have a way to point you to where to start looking. I did this by catching otherwise unhandled exceptions on "user and system end points" that I selected for this purpose.
Error box or not, try to find a way to not throw the user out of context when something goes wrong. It is hard to make it work in all cases though, but it is fatal when it happens.
You can capture unhanded (and thread) exceptions using the Application.ThreadException and AppDomain.CurrentDomain.UnhandledException properties.
Your Main would look something like this:
[STAThread]
static void Main() {
if (Debugger.IsAttached) {
Run();
return;
}
Application.ThreadException += ApplicationThreadException;
AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException;
Run();
}
Note the debugger check, just so the debugger can catch these exceptions when your developing.
The Run function is pretty simple
static void Run() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
And then the two exception handlers.
static void ApplicationThreadException(object sender, ThreadExceptionEventArgs e) {
ErrorInformationDialog eid = new ErrorInformationDialog(e.Exception.Message, e.Exception);
eid.ShowDialog();
}
static void CurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) {
ErrorInformationDialog eid = new ErrorInformationDialog(e.ExceptionObject as Exception);
eid.ShowDialog();
}
And ErrorInformationDialog is just a form I put together to display an error notification and give instructions for reporting it.

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

This is getting extremely irritating. Right now I have a winforms application, and things were not working right, but no exceptions were being thrown as far as I could tell. After stepping through almost all pieces of relevant code, it turns out that an exception was being thrown at the start of my application.
Long story short, in WinForms, being as awesome as it is, if an exception occurs the WinForms library ignores it. No "an unhandled exception has occurred" JIT message is thrown, it just stops processing the current event and goes back to the GUI.
This is causing random bugs, because code to load data isn't being called due to the exception occurring prior to this data being loaded.
To see this in action I created a brand new WinForms application, and entered the following code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string blah = null;
blah.Trim();
}
}
Press F5 and the form loads without any errors showing, even though a null reference is being thrown.
I then tried to go to my Program.cs main method and add Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); to it. Still my form loads without causing any errors to be thrown.
Even though I know that I can tell VS to break on all exceptions, I find this situation really bad. It causes really wierd issues that are hard to debug in production, and as this is an internal tool I really want to have it so it actually errors out when an exception occurs, and not silently disregards it.
Does anyone know how to do this?
Update: Just to update on things I have learned from the comments.
This does appear to be a 64-bit issue with windows, as I learned from this question which I did not see before posting. In that question it pointed to a Microsoft bug report about this, which had this to say:
Hello,
This bug was closed as "External" because this behavior results from how x64 version of Windows handle exceptions. When a user mode exception crosses a kernel transition, x64 versions of Windows do not allow the exception to propagate. Therefore attached debuggers are unaware of the fact that an exception occured resulting in the debugger failing to break on the unhandled exception.
Unfortunately where is nothing that the Visual Studo team can do to address this, it is the result of operating system design. All feedback regarding this issue should be addressed to the Windows team; however the Windows team considers this to be the "correct" operating system design, and considers the x86 behavior to be "incorrect".
Best Regards,
Visual Studio Debugger
That being said, builds not run through visual studio (or using Ctrl+F5 to run) does seem to show the JIT exception message box EXCEPT if you have the following code in your Program.cs:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
That code will cause windows to ignore the exception.
However, if you (instead) subscribe to the Application.ThreadException event, not only will your exceptions be caught, visual studio's debugger will break on 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);
}
Try the following.
Handle exceptions in your main application entry point.
Also, manage unhandled thread exceptions using a ThreadExceptionEventHandler
This is the code snippet:
[STAThread]
public static void Main(string[] args)
{
try
{
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
//your program entry point
}
catch (Exception ex)
{
//manage also these exceptions
}
}
private void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
ProcessException(e.Exception);
}
An easy fix is not to run under the debugger.
The debugger is masking the exception for some reason. If you run your app normally (Ctrl+F5), you'll get the usual "Unhandled exception has occurred in your application... Continue/Quit?" dialog.
Having experienced this often and identified the issue regarding 64 bit OS and the Form.Load event, I always just make a point of doing all my start up functions in the Form.Shown event. For all practical purposes this is the same thing (aside from a few rare, exceptional circumstances), and the JIT message is produced in the Shown event.

Try-Catch in Program.cs only works when started from visual studio

I tried to write a little crash reporter for uncatched expetions. This works perfectly when starting my App in VS.
But as soon as I try to start the .exe it only shows me the standard "There is an uncaught expetion"-thingy from windows.
And no it's not the crashreporter which crashes.
This is my code in the Program.cs
try
{
Application.Run(new TestServer());
}
catch (Exception e)
{
Application.Run(new CrashReporter(e.StackTrace.ToString()));
}
}
This is because you use a debugger. Winforms detects this and disables the event handler for Application.ThreadException. That's important, it lets you debug exceptions. To get your catch clause to work without a debugger, you'll have to add this statement to your Main() method, before the Run() call:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
It now does make more sense to write an event handler for AppDomain.Current.UnhandledException instead, you'll also get notified about unhandled exceptions in worker threads.
Instead of this you can handle following event (which is the preferred way of handling unhandled application exceptions):
AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
{
Application.Run(new CrashReporter(e.StackTrace.ToString()));
}
Application.Run(new TestServer());
Are you running on a 64 bit OS? This sounds like the problem Hans Passant answered here.
Debugging can swallow errors on Form construction and Forms_Load in 64 bit CLR...
Are you sure this thing works? I mean, did this strategy work for you previously?
I use (and suggested way) this way to catch the unhandled exceptions globally:
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
//then start the main form...
Application.Run(new TestServer());
Here is the documentation
http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx
CrashReporter is causing it. An uncaught exception in a catch statement will cause an uncaught exception. You need another try/catch in your catch and another fall back.

What's a good general way of catching a StackOverflow exception in C#?

If I have a method that I know could potentially recurse infinitely, but I can't reliably predict what conditions/parameters would cause it, what's a good way in C# of doing this:
try
{
PotentiallyInfiniteRecursiveMethod();
}
catch (StackOverflowException)
{
// Handle gracefully.
}
Obviously in the main thread you can't do this, but I've been told a few times it's possible to do it using threads or AppDomain's, but I've never seen a working example. Anybody know how this is done reliably?
You can't. From MSDN
Starting with the .NET Framework
version 2.0, a StackOverflowException
object cannot be caught by a try-catch
block and the corresponding process is
terminated by default. Consequently,
users are advised to write their code
to detect and prevent a stack
overflow. For example, if your
application depends on recursion, use
a counter or a state condition to
terminate the recursive loop. Note
that an application that hosts the
common language runtime (CLR) can
specify that the CLR unload the
application domain where the stack
overflow exception occurs and let the
corresponding process continue. For
more information, see
ICLRPolicyManager Interface and
Hosting Overview.
There is no way to catch StackOverflowException, but you can do something with unhandled exception:
static void Main()
{
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}
static void CurrentDomain_UnhandledException
(object sender, UnhandledExceptionEventArgs e)
{
try
{
Exception ex = (Exception)e.ExceptionObject;
MessageBox.Show("Whoops! Please contact the developers with the following"
+ " information:\n\n" + ex.Message + ex.StackTrace,
"Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
finally
{
Application.Exit();
}
}

Categories

Resources