Attaching the .net Debugger While Keeping Useful Dead Logging

I would like to have some kind of exception mechanism for everyone at the root of my code, so when the application unexpectedly exits, I can still provide some useful logging.

Something along the lines

static void Main () { if (Debugger.IsAttached) RunApp(); else { try { RunApp(); } catch (Exception e) { LogException(e); throw; } } } 

While everything is working fine, my problem is that I want to attach the debugger after the exception has been thrown.

Since the exception goes beyond the runtime, windows will ask for the attachment of the visual studio, except that since it was restarted, all locales and parameters located further on the stack were lost.

Is it necessary to record these exceptions at all, while preserving the way the debugger is connected and preserving all the useful information?

+6
debugging stack-trace c #
source share
7 answers

As Paul Betts already mentioned, you might be better off using an AppDomain.UnhandledException instead of a try / catch block.

In the UnhandledException event handler, you can log / throw an exception and then offer debugging capability, for example. show a form with exception details and buttons for ignoring, debugging, or terminating.

If the user selects the debugging option, call System.Diagnostics.Debugger.Break () , which allows the user to attach any debugger that they want the entire call stack to be accessible.

Obviously, you can disable this option for any assemblies that, as you know, you are never going to attach to the debugger.

 class Program { static void Main() { AppDomain.CurrentDomain.UnhandledException += ExceptionHandler; RunApp(); } static void ExceptionHandler(object sender, UnhandledExceptionEventArgs e) { Console.WriteLine(e.ExceptionObject); Console.WriteLine("Do you want to Debug?"); if (Console.ReadLine().StartsWith("y")) Debugger.Break(); } static void RunApp() { throw new Exception(); } } 
+15
source share

Awfully hacked, but without runtime hooks (I don't know anything) is the only way to get to the stack frame from which you throw ....

All exceptions that are known to be output from the terminal should have the following in their constructor:

 #if DEBUG System.Diagnostics.Debugger.Launch() #endif 

This will be a dialog that allows the user to either provide the appropriate debugger or select “no”, and there will be no debugging (in any case, the exception will end and then be thrown. This, obviously, works only on exceptions whose source you control.

I do not recommend this, in the debug assembly with the debugger attached, you can simply choose to get a "first chance", an exception break, which should usually be sufficient for your needs.

Another option is to start programming mini-dumps programmatically on exception sites, such data can then be checked later with a tool like windbg, but do not interfere too much with the desired exception behavior that unwinds the stack after.

The act of exclusion falling into your catch-all trap is exactly the stack that you don't need, sorry. If you like C ++ and you like it, you can create a small (but difficult to get right) mono fork, because of which all exceptions trigger the debugger. Or simply rebuild the BCL Exception monoclass to do the same as described above.

+2
source share

Why don't you just let it crash and then sign up for Microsoft Windows Error Reporting? See http://msdn.microsoft.com/en-us/isv/bb190483.aspx for more details.

If you do not want to do this, you can use the IsDebuggerPresent function ( http://msdn.microsoft.com/en-us/library/ms680345.aspx ), and if the result is False, instead of wrapping your code in try-catch , add an event handler to the AppDomain.UnhandledException event ( http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx )

+1
source share

Should not just do

 Exception e1 = e; LogException(e); throw(e1); 

does the trick inside the catch (at least you can examine the external exception)?

0
source share

If you are strictly using Debug mode for development and release mode for deployment, you can try using the System.Diagnostics.Debugger class.

 catch (Exception e) { #if DEBUG System.Diagnostics.Debugger.Launch() #endif LogException(e); throw; } 
0
source share

You can get information about the exception by writing to the trace log:

  private static void Main(string[] args) { try { // ... } catch (Exception exception) { System.Diagnostics.Trace.Write(exception); #if DEBUG System.Diagnostics.Trace.Write("Waiting 20 seconds for debuggers to attach to process."); System.Threading.Thread.Sleep(20000); System.Diagnostics.Trace.Write("Continue with process..."); #endif throw; } } 

Use DebugView to display the trace log. Stopping the thread for a few seconds will give you some time to attach your debugger to the process without losing the original exception.

0
source share

If none of the global events work, then what you could try is to put errors in any events that your software processes. The ease of this depends on the complexity of your applications. Many applications written using the .NET platform are written to handle events, whether it is a traditional application or a web application. By placing hooks in the events themselves, you should be able to save information on the stack that you need.

0
source share

All Articles