Trace all handled exception - c#

I am trying to understand why a deployed application is not working properly. I have pinned down the problem to a particular update routine. Sadly, the routine is embedded into a do nothing try-catch.
bool requireUpdate = false;
try
{
requireUpdate = !client.IsUpToDate();
}
catch{ }
I need a way to get the exception without having to recompile and do a deploy.
Is there is a way to modify the app.config file so it can trace all handled exceptions to a log file, regardless of how they have been handled?

Just because I discovered this today (and I really like resurrecting old questions with not-too-helpful answers!), since .NET4, there is a new event on AppDomain, which fires before any exception handling.
At some point in the setup code for your app (e.g. Program.Main, Application_OnStart, etc), you can add a handler:
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.FirstChanceException
+= FirstChanceException
// ...rest of your app startup
}
private static bool LogFirstChanceExceptions
{
get
{
return ConfigurationManager.AppSettings["logFirstChanceExceptions"]
.Equals(bool.TrueString)
}
}
private static void FirstChanceException(object sender,
FirstChanceExceptionEventArgs e)
{
if (e != null &&
e.Exception != null &&
LogFirstChanceExceptions)
{
Console.Error.WriteLine("First-chance {0}: {1}",
e.Exception.GetType(),
e.Exception.Message);
}
}
}
(Untested, no warranty, etc. Not pictured: any re-entrancy handling, in case the FirstChanceException handler itself throws an exception)
Doesn't help the OP, but it might help people who can recompile, to include something that allows them to toggle this kind of tracing in the future.

Unfortunately there is nothing that can be done about handled exceptions, as they are handled (even if very badly, as in your case).
The best way to get them will be to rewrite/recompile/deploy.

UPDATED
CLR profiling can help ya!
Have a look at this link:
http://msdn.microsoft.com/en-us/magazine/cc301839.aspx
You can basically track your exceptions:
"he profiling API offers an extensive set of callbacks that depict in detail the search, unwind, and finally phases of the exception handling cycle. An interesting profiling scenario would monitor managed exceptions and provide additional information such as the Win32 thread that threw the exception, the function that was on the top of the stack, the arguments of that function, and the locals that were in scope at the point where the exception occurred."

Use low level debuggers, such as WinDbg you will be able to know first chance exceptions.

Tricks I've used for this in Java:
Go through all of the catch blocks in the application, looking for empty ones. Add a debug or trace message to the block saying something like, "Catching expected exception", and the exception. You should have this anyway, and set a policy that silently swallowing exceptions is absolutely not acceptable.
If that fails to flush out the exception, recompile the base Exception, add a block to the no-arg constructor to log a stack trace if the application is in debug (or trace) mode. Obviously this is easier to do if your application/library has its own Exception heirarchy, but there are ways to inject this behavior (here the way to do this in C# would be distinct from how I'd accomplish this)

There's another option, but it may or may not be pretty: Moles.
Technically used for unit testing, Moles allows you to replace any .NET method with a delegate. You might be able to use it to replace that method with your delegate that does what you want instead.
You might be able to replace the original method with a delegate that calls client.IsUpToDate() so you can snag the exception instead?
Moles is part of Pex:
http://research.microsoft.com/en-us/projects/pex/default.aspx

This solution may be what you are looking for.
Basically the instruction is to use this block of code:
System.Diagnostics.EventLog.WriteEntry("MyEventSource", exception.StackTrace,
System.Diagnostics.EventLogEntryType.Warning);
Additionally the app.config from that same link seems to be like so:
<system.diagnostics>
<switches>
<add name="MySwitch" value="Verbose" />
</switches>
<trace autoflush="true">
<listeners>
<add name="EventLogger"
type="System.Diagnostics.EventLogTraceListener"
initializeData="NameOfYourApplication" />
</listeners>
</trace>

Related

Any way to catch an exception occurring on a thread I don't own?

I'm using a crappy third party library because unfortunately I have no choice. This library creates a bunch of threads internally when I call it, and occasionally throws a NullReferenceException on one of these threads. Is there any way for me to catch these exceptions even though I don't own the thread that throws them? I have no way to change the third party code.
As a simple example to show the problem:
public static void main()
{
try
{
var crappyLib = new CrappyLibrary();
crappyLib.DoCrappyThings();
}
catch
{
Console.WriteLine("This never happens");
}
}
// I do not own the following code, I can't change it
public class CrappyLibrary
{
public void DoCrappyThings()
{
var t = new Thread(DoWork);
t.Start();
}
private void DoWork()
{
throw new ThisLibrarySucksException();
}
}
The thing worrying me most in the described case is abnormal thread termination inside that 3rd-party lib. Once a thread is throwing, you can't catch the exception via correct way because you're not the owner of that thread invocation (and it has no idea it should propagate the exception to you; unlike it happens in TPL, let say). So even if handling such exceptions via a global handler this could be incorrect way because the lib can appear in non-consistent state after any of such exceptions.
So the safe way here is to isolate the lib inside some scope and re-launch the scope after any exception. Let say, to load the lib into separate domain.
If your goal is to prevent early termination of your process because of these unhandled exceptions that are not under your control, then there exists the legacyUnhandledExceptionPolicy setting that you can add to your app.config that will prevent unhandled thread exceptions from terminating the whole process.
Obviously, the solution is not perfect, as unhandled exceptions can destabilize the state of the threads. But at least it's an option you can consider.
Please have a look at the documentation about this here to better understand the implications of turning on this setting.
Your app.config would have to look something like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="1"/>
</runtime>
</configuration>
EDIT:
Just a thought, but perhaps the above setting, in combination with adding an event handler for AppDomain.UnhandledException can help you with your need.
Using AppDomain.UnhandledException, you can detect the failure, so that you know when you need to trigger a retry, or whatever else it is that you need to do in these cases.
And the legacyUnhandledExceptionPolicy setting would still be useful to prevent the process from shuting down, thus giving you the opportunity to perform the retry.
I hope this is helpful https://msdn.microsoft.com/en-GB/library/system.windows.forms.application.threadexception.aspx
You can try something like that (it's from the article)
Application.ThreadException += new ThreadExceptionEventHandler (ErrorHandlerForm.Form1_UIThreadException);
// Set the unhandled exception mode to force all Windows Forms errors to go through
// our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
// Add the event handler for handling non-UI thread exceptions to the event.
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

Simulate Exception in Environment.Exit

A production console application that is shut down via Environment.Exit(0) every night prior midnight, occasionally experiences an exception during .Exit() which leaves the console application hanging, with an "Application has stopped working" screen.
This causes the process not to clean up properly and a relaunch after midnight fails because the prior process is still lingering.
Since I couldn't pin down what causes the exception in Environment.Exit, I'd like to at least handle it gracefully when it occurs and ensure that the process shuts down entirely. To do that, I'd like to simulate a crash after .Exit() but I wasn't able to find a scenario yet that would produce an exception during .Exit().
Does anyone have an idea how an exception during Environment.Exit could be simulated?
Sure, it's easy enough to duplicate:
private static void Main()
{
try
{
new ItsATrap();
Environment.Exit(0);
}
catch (Exception ex)
{
Console.WriteLine("During exit: {0}", ex);
}
}
private class ItsATrap
{
~ItsATrap()
{
throw new InvalidOperationException("Ooops!");
}
}
Note that the During exit text is never printed in the example above.
You can catch unhandled exceptions by installing a handler like this:
AppDomain.CurrentDomain.UnhandledException += (sender, args)
=> Console.WriteLine("Unhandled: {0}", args.ExceptionObject);
This way you have an opportunity to log them.
So... check your finalizers to see if they can throw.
Also, make sure they don't use other managed resources, as the finalization order isn't deterministic. As usual, Eric Lippert has some good articles to read on the subject.
You have an XY-problem here. You want to simulate an exception because you have no idea what else you could do. Instead of simulating something you don't exactly know, you should try to find out the real cause of the issue and fix it.
Collect a crash dump (MSDN) and load it into Visual Studio. As long as it's somewhere in your C# code, it should show you the line number.
See also: How do I take a good crash dump for .NET? here on Stack Overflow.
Modifying your code as proposed in other answers may change the timing and could just make the exception less likely or occur in different positions. Be happy that you can reproduce the problem and fix it instead of diluting it.
Use of a disposed/finalized object can probably cause it. This happens because there is no fixed order for finalization, so for example an hand-made logger that tries to write something on a Stream that has been finalized will cause an exception (hand made because "professional" loggers know of this :-) ).
You could try installing a first-chance exception handler just before calling the Environment.Exit that logs every exception that happens during this time. Something like:
object lck = new object();
AppDomain.CurrentDomain.FirstChanceException += (sender, e) =>
{
lock (lck)
{
File.AppendAllText("log.txt", string.Format("{0}: {1}", DateTime.Now, e.Exception.ToString()));
}
};
Environment.Exit(0);

log4net's LogManager.GetLogger() throws NullReferenceException when used in custom TraceListener

I am attempting to transition a large application from using the Trace class to output notifications through log4net. As such, I wrote a custom TraceListener to redirect output into the log4net's messaging (inspired by this post).
public class Log4netTraceListener : TraceListener
{
private static readonly ILog logger = LogManager.GetLogger("Log4netTraceListener"); // Line 19
public Log4netTraceListener() { /* nothing special */ }
public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message)
{
// some switching based on the TraceLevel, but eventually something like:
logger.Error(message);
}
}
The console application solution was three projects:
RunShipOrder - the console project that is the entry point for the application
ShipOrderAPI - a class library project that contains all of the code relevant to this process
CodeLibrary - a class library project that contains code common across many projects.
Log4netTraceListener is in this project
Inside of the RunShipOrder project, I can call LogManager.GetLogger("Log4netTraceListener"), and it works as expected. However, if I try to call a method on Trace it throws an exception. I have traced it back to the initial call to LogManager.GetLogger("Log4netTraceListener") inside of the Log4netTraceListener class.
The Exception thrown is a ConfigurationErrorsException, with an inner exception of TypeInitializationException, with an inner exception of NullReferenceException.
The stack trace on the innermost exception is:
at log4net.Core.LoggerManager.GetLogger(Assembly repositoryAssembly, String name)
at log4net.LogManager.GetLogger(Assembly repositoryAssembly, String name)
at log4net.LogManager.GetLogger(String name)
at CodeLibrary.Diagnostics.Log4netTraceListener..cctor() in Log4netTraceListener.cs:line 19
Any ideas on what might be throwing this exception from within the log4net codebase?
#drovani - excellent description. I was seeing the same symptoms. The issue in my case was that the System.Diagnostics.Trace output in app.config was configured to be a custom System.Diagnostics.TraceListener implementation that forwarded tracing to log4net, while at the same time enabling log4net's Internal Debugging via log4net.Internal.Debug = True in the app.config (or in code via log4net.Util.LogLog.InternalDebugging = true).
What is likely happening is you are calling LoggerManager.GetLogger() in your custom System.Diagnostics.TraceListener implementation during static initialization or just prior to logging, which then creates static initialization ordering issues. log4net is attempting to log something when it is doing its initialization but before LoggerManager is initialized. Therefore LoggerManager.GetLogger() throws the null reference exception.
In your custom TraceListener you can somewhat guard against this by using a static property to initialize the ILogger on first use instead of in a field, but you need to be careful here. The best thing to do is not log, or log using another mechanism if log4net.Util.LogLog.InternalDebugging is true. This would be the preferred solution.
Take a look at the source for log4net.Util.LogLog class. This logs to Trace by default, and you'll end up deadlocked if anything gets logged by this - such as an appender error. In your implementation of TraceListener, I'd make sure to set log4net.Util.LogLog.EmitInternalMessages = false in the constructor of your implementation, and perhaps handle the LogLog.LogReceived event and log those messages in another way. The sad part about this is that some appender errors will not be logged due to this setting. The log4net source is your friend here.
If you want to be really tricky, at a huge impact to performance, you'd need to check the setting of log4net.Util.LogLog.InternalDebugging before both logging a message and creating a logger. If enabled, you can get a stack trace and walk it to make sure that log4net is not in the stack prior to calling into log4net. If log4net is in the stack trace, you can pinvoke OutputDebugString() or use some other logging mechanism to trace the log4net internal log output. You absolutely do not want to redirect internal log4net debug messages to log4net else risk an exception that is named similarly to this excellent site.

How to check if Thread code runs in try-catch block

I would like to validate our code and check if every Thread that we execute runs in try catch block.
A valid sample:
Thread loadDataThread = new Thread(new ThreadStart(LoadData));
public void LoadData()
{
try {/*do something*/}
catch(Exception ex) { /*Handle exception*/ }
}
Not valid sample:
Thread loadDataThread = new Thread(new ThreadStart(LoadData));
public void LoadData()
{
/* do something */
}
Is this something that could be verified with FxCop or some other tool. The similar rule could be applied for some other things eg. Timer Ticks etc...
See http://social.msdn.microsoft.com/Forums/en-US/vstscode/thread/a257a910-126e-4c8d-aab3-3199347346ec for an example of how to detect a wrapping try/catch block in an FxCop rule. What's actually quite a bit trickier to do is detect which methods are susceptible to being run from a background thread since they're not all spawned using obvious launchers like Thread.Start or ThreadPool.QueueUserWorkItem.
That said, you might want to reconsider switching your approach from adding wrapping try/catches to using custom thread launchers that add the try/catch for you. (You could then create an FxCop rule to verify that the custom launchers/helpers are being used instead of the base framework analogs.) This would have the advantage of allowing you to systematically apply other changes to all thread (e.g.: setting cultures, tracking launching stack trace for use in later exception logging, etc.) without needing to change all the methods run from spawned threads.
I do not know if you can add a custom rule for this in FXCop, but you could use Mono.Cecil to do this, but it is not that simple.
This is a very good resource for rolling your own FxCop rule. You may find many other by googling for the same.
I believe that you can start looking at callers for Thread constructor. Then in calling statement, you can get address of thread procedure by looking at the delegate parameter. Once method ref is obtained, you need inspect statements within method body for the structure you are hoping for.
this does not answer your question directly but is probably pertinent.
Are you interested in doing the above because you do not want your application to exit/crash when a thread throws an uncaught Exception? If yes, then you can add the following to your app.config file in the configuration section:
<runtime>
<legacyUnhandledExceptionPolicy enabled="1"/>
</runtime>
disclaimer Doing the above is not recommended but may be used in a situation of last resort.
Warning: If you decide to use the above your application will not report any errors and go on executing as best it can. As a result you should have a handler that will at least log any uncaught exceptions via
void AppStartup()
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
//log error
}

Globally catch exceptions in a WPF application?

We have a WPF application where parts of it may throw exceptions at runtime. I'd like to globally catch any unhandled exceptions and log them, but otherwise continue program execution as if nothing happened (kinda like VB's On Error Resume Next).
Is this possible in C#? And if so, where exactly would I need to put the exception handling code?
Currently I can't see any single point where I could wrap a try/catch around and which would catch all exceptions that could occur. Even then, I would have left whatever has been executed because of the catch. Or am I thinking in horribly wrong directions here?
ETA: Because many people below pointed it out: The application is not for controlling nuclear power plants. If it crashes, it's not that big a deal, but it throws random exceptions that are mostly UI-related that are a nuisance in the context where it would be used. There were (and probably still are) a few of those and since it uses a plugin architecture and may be extended by others (also students in that case; so no experienced developers that are able to write completely error-free code).
As for the exceptions that get caught: I do log them to a log file, including the complete stack trace. That was the whole point of that exercise. Just to counter those people that were taking my analogy to VB's OERN too literally.
I know that blindly ignoring certain classes of errors is dangerous and might corrupt my application instance. As said before, this program isn't mission-critical for anyone. No-one in their right mind would bet the survival of the human civilization on it. It's simply a little tool for testing certain design approaches wrt. software engineering.
For the immediate use of the application there are not many things that can happen on an exception:
No exception handling – error dialog and application exit. Experiment has to be repeated, though likely with another subject. No errors have been logged, which is unfortunate.
Generic exception handling – benign error trapped, no harm done. This should be the common case judged from all errors we were seeing during development. Ignoring this kind of errors should have no immediate consequences; the core data structures are tested well enough that they will easily survive this.
Generic exception handling – serious error trapped, possibly crash at a later point. This may happen rarely. We've never seen it so far. The error is logged anyway and a crash might be inevitable. So this is conceptually similar to the very first case, except that we have a stack trace. And in the majority of cases the user won't even notice.
As for the experiment data generated by the program: A serious error would at worst just cause no data to be recorded. Subtle changes that change the result of the experiment ever so slightly are pretty unlikely. And even in that case, if the results seem dubious the error was logged; one can still throw away that data point if it's a total outlier.
To summarize: Yes, I consider myself still at least partially sane and I don't consider a global exception handling routine which leaves the program running to be necessarily totally evil. As said twice before, such a decision might be valid, depending on the application. In this case it was judged a valid decision and not total and utter bullshit. For any other application that decision might look different. But please don't accuse me or the other people who worked on that project to potentially blow up the world just because we're ignoring errors.
Side note: There is exactly one user for that application. It's not something like Windows or Office that gets used by millions where the cost of having exceptions bubble to the user at all would be very different in the first place already.
Use the Application.DispatcherUnhandledException Event. See this question for a summary (see Drew Noakes' answer).
Be aware that there'll be still exceptions which preclude a successful resuming of your application, like after a stack overflow, exhausted memory, or lost network connectivity while you're trying to save to the database.
Example code using NLog that will catch exceptions thrown from all threads in the AppDomain, from the UI dispatcher thread and from the async functions:
App.xaml.cs :
public partial class App : Application
{
private static Logger _logger = LogManager.GetCurrentClassLogger();
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
SetupExceptionHandling();
}
private void SetupExceptionHandling()
{
AppDomain.CurrentDomain.UnhandledException += (s, e) =>
LogUnhandledException((Exception)e.ExceptionObject, "AppDomain.CurrentDomain.UnhandledException");
DispatcherUnhandledException += (s, e) =>
{
LogUnhandledException(e.Exception, "Application.Current.DispatcherUnhandledException");
e.Handled = true;
};
TaskScheduler.UnobservedTaskException += (s, e) =>
{
LogUnhandledException(e.Exception, "TaskScheduler.UnobservedTaskException");
e.SetObserved();
};
}
private void LogUnhandledException(Exception exception, string source)
{
string message = $"Unhandled exception ({source})";
try
{
System.Reflection.AssemblyName assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName();
message = string.Format("Unhandled exception in {0} v{1}", assemblyName.Name, assemblyName.Version);
}
catch (Exception ex)
{
_logger.Error(ex, "Exception in LogUnhandledException");
}
finally
{
_logger.Error(exception, message);
}
}
AppDomain.UnhandledException Event
This event provides notification of uncaught exceptions. It allows the
application to log information about the exception before the system
default handler reports the exception to the user and terminates the
application.
public App()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
}
static void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception) args.ExceptionObject;
Console.WriteLine("MyHandler caught : " + e.Message);
Console.WriteLine("Runtime terminating: {0}", args.IsTerminating);
}
If the UnhandledException event is handled in the default application
domain, it is raised there for any unhandled exception in any thread,
no matter what application domain the thread started in. If the thread
started in an application domain that has an event handler for
UnhandledException, the event is raised in that application domain. If
that application domain is not the default application domain, and
there is also an event handler in the default application domain, the
event is raised in both application domains.
For example, suppose a thread starts in application domain "AD1",
calls a method in application domain "AD2", and from there calls a
method in application domain "AD3", where it throws an exception. The
first application domain in which the UnhandledException event can be
raised is "AD1". If that application domain is not the default
application domain, the event can also be raised in the default
application domain.
In addition what others mentioned here, note that combining the Application.DispatcherUnhandledException (and its similars) with
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="1" />
</runtime>
</configuration>
in the app.config will prevent your secondary threads exception from shutting down the application.
Here is complete example using NLog
using NLog;
using System;
using System.Windows;
namespace MyApp
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private static Logger logger = LogManager.GetCurrentClassLogger();
public App()
{
var currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var ex = (Exception)e.ExceptionObject;
logger.Error("UnhandledException caught : " + ex.Message);
logger.Error("UnhandledException StackTrace : " + ex.StackTrace);
logger.Fatal("Runtime terminating: {0}", e.IsTerminating);
}
}
}
in Wpf application Project follow this Steps:
in App.xaml.cs file:
using 'System.Windows.Threading'
create App_DispatcherUnhandledException method same example.
example:
using System.Windows;
using System.Windows.Threading;
namespace Test
{
public partial class App : Application
{
void App_DispatcherUnhandledException(object sender,
DispatcherUnhandledExceptionEventArgs e)
{
// Process unhandled exception
// Prevent default unhandled exception processing
e.Handled = true;
}
}
}
in App.xaml:
add DispatcherUnhandledException="App_DispatcherUnhandledException"
for Example:
<Application x:Class="eValGr.UI.Light.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:eValGr.UI.Light"
DispatcherUnhandledException="Application_DispatcherUnhandledException">
<Application.Resources>
</Application.Resources>
</Application>
Like "VB's On Error Resume Next?" That sounds kind of scary. First recommendation is don't do it. Second recommendation is don't do it and don't think about it. You need to isolate your faults better. As to how to approach this problem, it depends on how you're code is structured. If you are using a pattern like MVC or the like then this shouldn't be too difficult and would definitely not require a global exception swallower. Secondly, look for a good logging library like log4net or use tracing. We'd need to know more details like what kinds of exceptions you're talking about and what parts of your application may result in exceptions being thrown.

Categories