Static Code Analysis to find code outside a try/catch block? - c#

We have quite a large c# application (1m lines+) and it is highly multithreaded. For each thread that gets launched we need to ensure that there is a try/catch block in the right place to catch errors that might crash the application.
I am wondering if there are any static code analysis tools out there than can scan the code and find points outside any try catch?
I saw on this thread: Way to automatically see which functions can potentially return exception in c# that RedGate used to have Exception Hunter, but this product has been withdrawn.
What I'm looking for would be much simplier than Exception Hunter - it would just find 'naked code' which was outside any try/catch, and highlight it.

Try Reflection first. For example you can use MethodBody to query for exception handling.
If it's not good enough, move to CCI: http://ccimetadata.codeplex.com/

Related

Exception thrown not caught by a `catch` block [duplicate]

NOTE ADDED AFTER SOLUTION: An AccessViolationException was being thrown inside the method called by reflection. This was the reason the TargetInvocationException couldn't be caught.
NOTE: This is OUTSIDE of the IDE. The referenced question is NOT the same.
TL;DR
Can't get a stack trace
Can't get inner exceptions
Can't use debugger (copy protection scheme of a third party library gets in the way)
Any changes to the code prevent the exception from occurring - means I can't add logging to find out where the exception occurrs
How can I get the exception to be caught or get the needed information some other way?
Long description:
I am having a problem with an exception that occurs in a method that gets called by reflection. The exception itself actually occurs in the called method, but since the method is called by reflection, the real exception gets wrapped in a System.Reflection.TargetInvocationException. No problem, just catch it and get the internal exception - except the System.Reflection.TargetInvocationException doesn't get caught. My program crashes, and I get a dump along with an entry in the Windows event log.
The Windows event log doesn't contain the internal exceptions, and neither does the dump.
I can't attach a debugger to the program because then an external library (which is needed to get to the reflection call) won't run - copy protection, don't you know.
If I put a try/catch into the offending method, the exception doesn't occur - which is bad. The cause isn't fixed, it just doesn't happen any more.
The same effect happens if I put logging into the offending method - the exception doesn't occur any more.
I can't use logging, I can't use a debugger, and in the one place where I could catch the exception and log it the exception doesn't get caught.
I'm using Visual Studio 2010 and dotnet 4.0.
To make it clear: The try/catch doesn't work when the program is run outside of Visual Studio, and I can't run it inside of Visual Studio in the debugger because then the program can't reach the point where the exception occurs. This is NOT within the IDE.
Eliminating the reflection isn't an option (I've tried it for just the one case, and the exception goes away.)
The method being called does a lot of stuff, but breaking it down into smaller methods doesn't help - the exception just goes away.
The exception doesn't occur all the time, only when I do a certain sequence of steps - and when it occurs then it is always on the second time through the whole sequence.
In the sequence I am using, the method gets called by two threads almost simultaneously - a particular bunch of data gets entered, which causes a copy of a report and another document to be printed on two separate printers - one report and document to each printer. Since generating the reports and printing the document can take a while, they are done on threads in the background so the user can continue working.
I suspect that the threads are stepping on each others toes (lots of file and database manipulations going on) but without knowing what is really happening I can't fix it.
The code below shows a simplified version of the call by reflection.
Does any one have a suggestion as to what may be causing the System.Reflection.TargetInvocationException to not be caught, or maybe an alternative way to catch the inner exception?
Try
Dim methode As System.Reflection.MethodInfo
methode = GetType(AParticularClass).GetMethod("OneOfManyMethods", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static)
Dim resultobject As Object = methode.Invoke(Nothing, Reflection.BindingFlags.InvokeMethod Or Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static, Nothing, New Object() {SomeBooleanVariable, SomeStringVariable}, Nothing)
result = DirectCast(resultobject, DataSet)
Catch ex As Exception
'Log the error here.
End Try
Found the reason why I couldn't catch the exception:
The actual exception was an AccessViolationException, which can't be caught in dotnet 4.0 without taking special steps (How to handle AccessViolationException.)
To make things more fun, when AccessViolationException gets thrown in a method called by reflection, only a TargetInvocationException gets logged in the Windows event log, and only the TargetInvocationException is available in the dump.
Once I managed to get the real exception, I found that that it was a call to Application.DoEvents() from a non-GUI thread that caused the AccessViolation. DoEvents() can cause enough fun when called on the GUI-Thread (Use of Application.DoEvents()), let alone when called from a background thread.
Once that was fixed, I found that our third party library (the one with the copy protection) doesn't like being called simultaneously in separate instances. Fixing that was a matter of a synclock in the right place.
The code causing all of this fun was at one time all in the GUI-Thread, and was originally written back in the days of dotnet 1.1 - this explains the call to DoEvents. The code has been converted piece-wise to run in parallel in background threads through several different stages, with no one single developer having a complete overview of the process.
I am not sure I can replicate your issue, but this is how we get it and it work's just fine...
Try
'YOUR CODE'
Catch ex As Exception
'This is where we grab it from... It needs to be in this block to work...
System.Reflection.MethodInfo.GetCurrentMethod.ToString
End Try
Let me know how it work's out for you?

Is it possible to do Vectored Strctured exception handling in c#?

As far as i know, when a first chance exception occurs, the debugger is notified(if any) and then if still unhandled, the system searches for the nearest frame based exception handler in the stack if any.
I was reading this link when I came to know about vectored exception handling.
Question1) I was wondering if there is any way we can do that in managed code?
Question2) I think that any try{}catch{} is a frame based handler but what happens when we register a handle at certain events like
AppDomain.CurrentDomain.UnhandledException += (x, y) =>
{
Console.WriteLine("Unhandled exception");
};
what are these?
The debugger is only notified of an exception if it is attached. For example, if you are debugging in Visal Studio, then it would be called first, and if it passed on the exception, the exception handlers would be called. To have the debugger stop on all exceptions, from Visual Studio select the Debug menu and select Exceptions and then choose the exceptions you want the debugger to halt at. If none of those handlers (or there are no handlers) then the debugger would be called a 2nd time to stop execution and display a general message that an exception had occurred. If on the other hand, the debugger is not attached, then the debugger won't be notified - which is the case for 99%+ of all managed production code.
Vectored exception handling is a low level api intended to be used from unmanaged code - i.e. C++. Your very first choice from managed code (C#) should be to use structured exception handling with try/catch/finally blocks. Most (99%+) managed code developers using a language like C#, including myself, have found structured exception handling to be quite adequate.
If you still think you need to use this api, you will have to call AddVectoredExceptionHandler by using P/Invoke, which is one way unmanaged code can be called from managed code. There are a couple of caveats. See this link for a general overview. Mike Stall's blog suggests avoiding vectored exceptions in managed code. In this thread, Mike Stall says that unmanaged vector exception handlers should never call back into managed code. He also suggests that managed exceptions are an undocumented feature in vectored exception handling and that MS could eliminate that support in a future release of the CLR, so use at your own peril.
The AppDomain.UnhandledException event is only called when no other handler is found. It could be used in situations where it is desired to log some information about an unhandled exception, but there is little time to put in proper structured exception handling to a large base of existing code, or perhaps you don't have access to the code that is throwing the exception. Otherwise, try/catch/finally blocks should be used instead.
You might also try taking a look at the AppDomain.FirstChanceException event, which occurs before the first exception handler is called. This one might be useful if all you want to do is log some information for certain exceptions thrown in someone else's code that you don't have access to that are handled. It is only a notification though, and not an exception handler. I have never used it before, so don't know how much it might affect performance. My concern here is that Microsoft developers sometimes throw exceptions in the CLR for various things other than true errors. To see this in action, try setting the debugger to break on every exception, including the CLR Runtime exceptions. This can be done in Visual Studio from the Debug menu and choosing Exceptions. So, I don't know how much of an impact it would have on performance since all the CLR exceptions will probably raise this event as well. To be fair, the last time I did this was with VS 2008. This might not be true or as true with later versions of the CLR. I don't see a way to limit the exceptions this event will fire either. So, you would need to filter out the exceptions you are not interested in and experiment to guage its impact on performance.

Throw exception where the class was instantiated - C#

I am developing a library that will be used by programmers.
When I am throwing an exception, the debugger goes to where the exception was thrown, and not where the class was instantiated or the method was executed.
With a try .. catch this can be solved, but what if the programmer who is using the library does not open a try .. catch? he will see all my code!
How can I avoid this?
he will see all my code!
Well yes, if you distribute your code. If you don't, how would you expect the code to be seen? Don't forget that you're in a different situation to most developers using your library, as you have the source code on your machine. Try the same DLL on a machine which doesn't have the source code.
The developer may see a decompiled version of your code, perhaps - is that such a great problem? If so, you should look at obfuscating your code - but be aware that that comes with some logistical downsides too.
I suspect this really just isn't a problem.
Well, if you make a release version of your library and you don't provide debugger symbols (pdb) the debugger of the libraries user shouldn't show your code.
OTOH, do you know tools like reflector? Your code isn't really a secret.
If I understand what you are looking for I think you want to use a try catch in your code and instead of a catch block where you handle the exception you want to rethrow it like this:
try
{
//exception code
}
catch (Exception e)
{
throw e;
}
If I remember correctly, throwing like this will reset the stack trace whereas just a throw will keep the stack trace in tact.

The internal implementation of exception handling

Today, when I write a piece of code like this:
try
{
...
}
catch (Exception e)
{
...
}
I suddenly realize that the
catch (Exception e)
{
...
}
statement is so much like a function declaration. And I vaguely remembered that the exception handling involves some kind of stack walking/manipulation.
So, what exactly is the above exception handling code compiled into? I have the feeling that the above code is just a special/convenient syntax to ease our coding, but in fact, maybe our code is wrapped into an auto-generated exception handling function? I hope I made myself clear.
Fortunately for you CLR architect Chris Brumme wrote a long explanation of how exception handling works in the CLR. Now, this was written eight years ago and a few of the details are slightly different today, but this should at least give you a good start.
http://blogs.msdn.com/b/cbrumme/archive/2003/10/01/51524.aspx
This is a good place to start: http://msdn.microsoft.com/en-us/library/5b2yeyab.aspx#how_the_runtime_manages_exceptions
Basically, they are kind of like functions, but not really. They aren't called, per se, they have no separate stack frame (or separate stack, for that matter), using the current function's stack frame instead. That's why you can access local variables.
If you want to see what it compiles into, you can use ILDasm.exe to decompile an assembly that has exception blocks (so make a sample program and decompile it). Alternatively, use RedGate's Reflector for a better decompiling experience.
If the IL isn't enough, you can get at the generated assembly by running your program in debug mode in Visual Studio, setting a breakpoint in your method and then when that breakpoint is hit, opening the disassembly tab/window from the Debug menu.

Is there a more elegant way to do error handling than spreading try/catch in the entire app code?

I've found myself doing too much error handling with try\catch statements and getting my code ugly with that. You guys have any technique or framework to make this more elegant? (In c# windows forms or asp.net).
You need to read up on structured exception handling. If you're using as many exception handlers as it sounds then you're doing it wrong.
Exception handling isn't like checking return values. You are supposed to handle some exceptions in limited, key spots in your code not all over the place. Remeber that exceptions "bubble up" the call stack!
Here is a good and well-reviewed CodeProject article on exception best practices.
Java land had pretty the same problem. You just look at method and you can't at a first glance understand what it is doing, because all you see is try/catch blocks. Take a 30-40 line method and throw away all try statements and catch blocks and you might end up with 5-6 lines of pure application logic. This isn't such a big problem with C# as it has unchecked exceptions, but it gets really ugly in Java code. The funny thing is the try/catch blocks were intended to solve the very same problem in the first place. Back then it was caused by errno/errstr madness.
What the Java guys usually do is based on how do you typically handle exception. Most of the time you can't really do anything to correct the problem. You just notify the user that whatever he was trying to do didn't work, put back application in a certain state and maybe log and exception with complete stacktrace to log file.
Since you handle all the exceptions like this, the solution is to have a catch-all exception handler, which sits on top of application stack and catches all exceptions that are thrown and propagated up the stack. With ASP.NET you might use something like this:
http://www.developer.com/net/asp/article.php/961301/Global-Exception-Handling-with-ASPNET.htm
At the same time you are free to override that global handler by placing try/catch block in your code, where you feel something can be done, to correct the problem.
Just adding a Try Catch does not solve the problem. This topic a too big to handle as one question. You need to do some reading.
http://msdn.microsoft.com/en-us/library/8ey5ey87%28VS.71%29.aspx
http://www.codeproject.com/KB/architecture/exceptionbestpractices.aspx
Also FXCop, and VS Team System will warn you on some design issues.
Such heavy reliance on exception handling (in any language) does suggest that the mechanism is being misused. I always understood that exception handling was designed to trap the truly exceptional, unforeseeable event. It is not designed to handle (for instance) invalid data entry by a user - this is normal operation and your design and application coding must deal with such normal processing.
http://msdn.microsoft.com/en-us/library/ff664698(v=PandP.50).aspx
Check out Microsoft's Exception Handling Application Block. It has an intial learning curve, but is good stuff once you get it figured out.

Categories