I want to be able to break on Exceptions when debugging... like in Visual Studio 2008's Menu Debug/Exception Dialog, except my program has many valid exceptions before I get to the bit I wish to debug.
So instead of manually enabling and disabling it using the dialog every time is it possible to do it automatically with a #pragma or some other method so it only happens in a specific piece of code?
The only way to do something close to this is by putting the DebuggerNonUserCodeAttribute on your method.
This will ensure any exceptions in the marked method will not cause a break on exception.
Good explanation of it here...
This is an attribute that you put against a method to tell the debugger "Nothing to do with me guv'. Ain't my code!". The gullible debugger will believe you, and won't break in that method: using the attribute makes the debugger skip the method altogether, even when you're stepping through code; exceptions that occur, and are then caught within the method won't break into the debugger. It will treat it as if it were a call to a Framework assembly, and should an exception go unhandled, it will be reported one level up the call stack, in the code that called the method.
Code example:
public class Foo
{
[DebuggerNonUserCode]
public void MethodThatThrowsException()
{
...
{
}
What about conditional breakpoints? If I understand correctly, you can have a breakpoint fire only when the value of a certain variable or expression is true.
Wrap your try catch blocks in #if DEBUG
public void Foo()
{
#if DEBUG
try
#endif
{
//Code goes here
}
#if DEBUG
catch (Exception e)
{
//Execption code here
}
#endif
}
I like to keep the curly braces outside of the #if that way it keeps the code in the same scope if inside or outside of debug.
If you still want the execption handeling but want more detail you can do this
try
{
//code
}
catch (FileNotFoundException e)
{
//Normal Code here
#if DEBUG
//More Detail here
#endif
}
#if DEBUG
catch (Exception e)
{
//handel other exceptions here
}
#endif
This is a bit of too late for you, but this is the biggest reason I often try to teach people to use exceptions conservatively. Only use exceptions when something catastrophic has happened and your ability to reasonably continue is gone.
When debugging a program I often flip on First Chance Exceptions (Debug -> Exceptions) to debug an application. If there are a lot of exceptions happening it's very difficult to find where something has gone "wrong".
Also, it leads to some anti-patterns like the infamous "catch throw" and obfuscates the real problems. For more information on that see a blog post I made on the subject.
In terms of your problem, you can turn on first chance debugging for only a specific type of exception. This should work well unless the other exceptions are of the same type.
You could also use asserts instead of breakpoints. For instance, if you only want to breakpoint on the 5th iteration of a loop on the second time you call that function, you could do:
bool breakLoop = false;
...
Work(); // Will not break on 5th iteration.
breakLoop = true;
Work(); // Will break on 5th iteration.
...
public void Work() {
for(int i=0 ; i < 10 ; i++) {
Debug.Assert (!(breakLoop && i == 5));
...
}
}
So in the first call to Work, while breakLoop is false, the loop will run through without asserting, the second time through the loop will break.
Related
I would like Visual Studio to break when a handled exception happens (i.e. I don't just want to see a "First chance" message, I want to debug the actual exception).
e.g. I want the debugger to break at the exception:
try
{
System.IO.File.Delete(someFilename);
}
catch (Exception)
{
//we really don't care at runtime if the file couldn't be deleted
}
I came across these notes for Visual Studio.NET:
1) In VS.NET go to the Debug Menu >>
"Exceptions..." >> "Common Language
Runtime Exceptions" >> "System" and
select "System.NullReferenceException"
2) In the bottom of that dialog there
is a "When the exception is thrown:"
group box, select "Break into the
debugger"
3) Run your scenario. When the
exception is thrown, the debugger will
stop and notify you with a dialog that
says something like:
"An exception of type "System.NullReferenceException" has
been thrown.
[Break] [Continue]"
Hit [Break]. This will put you on the
line of code that's causing the
problem.
But they do not apply to Visual Studio 2005 (there is no Exceptions option on the Debug menu).
Does anyone know where the find this options dialog in Visual Studio that the "When the exception is thrown" group box, with the option to "Break into the debugger"?
Update: The problem was that my Debug menu didn't have an Exceptions item. I customized the menu to manually add it.
With a solution open, go to the Debug - Windows - Exception Settings (Ctrl+Alt+E) menu option. From there you can choose to break on Thrown or User-unhandled exceptions.
EDIT: My instance is set up with the C# "profile" perhaps it isn't there for other profiles?
There is an 'exceptions' window in VS2005 ... try Ctrl+Alt+E when debugging and click on the 'Thrown' checkbox for the exception you want to stop on.
Took me a while to find the new place for expection settings, therefore a new answer.
Since Visual Studio 2015 you control which Exceptions to stop on in the Exception Settings Window (Debug->Windows->Exception Settings). The shortcut is still Ctrl-Alt-E.
The simplest way to handle custom exceptions is selecting "all exceptions not in this list".
Here is a screenshot from the english version:
Here is a screenshot from the german version:
From Visual Studio 2015 and onward, you need to go to the "Exception Settings" dialog (Ctrl+Alt+E) and check off the "Common Language Runtime Exceptions" (or a specific one you want i.e. ArgumentNullException) to make it break on handled exceptions.
Step 1
Step 2
Check Managing Exceptions with the Debugger page, it explains how to set this up.
Essentially, here are the steps (during debugging):
On the Debug menu, click Exceptions.
In the Exceptions dialog box, select Thrown for an entire category of exceptions, for example, Common Language Runtime Exceptions.
-or-
Expand the node for a category of exceptions, for example, Common Language Runtime Exceptions, and select Thrown for a specific exception within that category.
A technique I use is something like the following. Define a global variable that you can use for one or multiple try catch blocks depending on what you're trying to debug and use the following structure:
if(!GlobalTestingBool)
{
try
{
SomeErrorProneMethod();
}
catch (...)
{
// ... Error handling ...
}
}
else
{
SomeErrorProneMethod();
}
I find this gives me a bit more flexibility in terms of testing because there are still some exceptions I don't want the IDE to break on.
The online documentation seems a little unclear, so I just performed a little test. Choosing to break on Thrown from the Exceptions dialog box causes the program execution to break on any exception, handled or unhandled. If you want to break on handled exceptions only, it seems your only recourse is to go through your code and put breakpoints on all your handled exceptions. This seems a little excessive, so it might be better to add a debug statement whenever you handle an exception. Then when you see that output, you can set a breakpoint at that line in the code.
There are some other aspects to this that need to be unpacked. Generally, an app should not throw exceptions unless something exceptional happens.
Microsoft's documentation says:
For conditions that are likely to occur but might trigger an exception, consider handling them in a way that will avoid the exception.
and
A class can provide methods or properties that enable you to avoid making a call that would trigger an exception.
Exceptions degrade performance and disrupt the debugging experience because you should be able to break on all exceptions in any running code.
If you find that your debugging experience is poor because the debugger constantly breaks on pointless exceptions, you may need to detect handled exceptions in your tests. This technique allows you to fail tests when code throws unexpected exceptions.
Here are some helper functions for doing that
public class HandledExceptionGuard
{
public static void DoesntThrowException(Action test,
Func<object?, Exception, bool>? ignoreException = null)
{
var errors = new List<ExceptionInformation>();
EventHandler<FirstChanceExceptionEventArgs> handler = (s, e) =>
{
if (e.Exception is AssertFailedException) return;
if (ignoreException?.Invoke(s, e.Exception) ?? false) return;
errors.Add(new ExceptionInformation(s, e.Exception, AppDomain.CurrentDomain.FriendlyName));
};
AppDomain.CurrentDomain.FirstChanceException += handler;
test();
AppDomain.CurrentDomain.FirstChanceException -= handler;
if (errors.Count > 0)
{
throw new ExceptionAssertionException(errors);
}
}
public async static Task DoesntThrowExceptionAsync(Func<Task> test,
Func<object?, Exception, bool>? ignoreException = null)
{
var errors = new List<ExceptionInformation>();
EventHandler<FirstChanceExceptionEventArgs> handler = (s, e) =>
{
if (e.Exception is AssertFailedException) return;
if (ignoreException?.Invoke(s, e.Exception) ?? false) return;
errors.Add(new ExceptionInformation(s, e.Exception, AppDomain.CurrentDomain.FriendlyName));
};
AppDomain.CurrentDomain.FirstChanceException += handler;
await test();
AppDomain.CurrentDomain.FirstChanceException -= handler;
if (errors.Count > 0)
{
throw new ExceptionAssertionException(errors);
}
}
}
If you wrap any code in these methods as below, the test will fail when a handled exception occurs. You can ignore exceptions with the callback. This validates your code against unwanted handled exceptions.
[TestClass]
public class HandledExceptionTests
{
private static void SyncMethod()
{
try
{
throw new Exception();
}
catch (Exception)
{
}
}
private static async Task AsyncMethod()
{
try
{
await Task.Run(() => throw new Exception());
}
catch (Exception)
{
}
}
[TestMethod]
public void SynchronousTest()
{
HandledExceptionGuard.DoesntThrowException(() => SyncMethod());
}
[TestMethod]
public async Task AsyncTest()
{
await HandledExceptionGuard.DoesntThrowExceptionAsync(() => AsyncMethod());
}
}
When I want to debug my application that throws exception, that means I need to disable the try-catch block like this:
#if !DEBUG
try
{
#endif
// Do something
#if !DEBUG
}
catch (ArgumentException)
{
Console.WriteLine("Something wrong");
}
#endif
Note: I know about break on handled exception of Visual Studio, but the downside is it break at every exception of the same type. EDIT to rephrase my meaning: For example, function A and B both throws NullReferenceException, but I only want to check when A throws it, but not B (handled NulRefExc in B is already correct).
One may ask why I need that. Usually I run ASP.NET MVC code without Debugging (but still in Debug build, which has DEBUG variable), and throwing exception is really great instead of catching it (in dev mode only, of course), because the error page with stack trace will be shown, so we can track the error much quicker.
Is there any cleaner way to write the upper code?
Since C# 6 you also may use exception filters for that:
try
{
// Do something
}
catch (ArgumentException) when (!Env.Debugging)
{
// Handle the exception
}
Having Env.Debugging defined somewhere as
public static class Env
{
#if DEBUG
public static readonly bool Debugging = true;
#else
public static readonly bool Debugging = false;
#endif
}
As an additional bonus you'll get original call stack in the exception object when it is not caught (due to when test failed, i.e. in debug). With a re-thrown exception you would have to provide the original exception as the inner one and make some extra effort to deal with it.
This approach also allows to enable/disable exception handling based on other condition, a web.config setting for example, which would allow you to swicth without recompilation:
public static class Env
{
public static readonly bool Debugging =
Convert.ToBoolean(WebConfigurationManager.AppSettings["Debugging"]);
}
just an idea
leave the try catch
then do
catch (ArgumentException)
{
#if DEBUG
throw SomeCustomExceptionYouCatchWith_break_on_handled_exception();
#endif
Console.WriteLine("Something wrong");
}
Two things:
How many places are you going to the put the #if DEBUG?
Console.WriteLine is meaningless in ASP.NET. See this for more.
What you should be doing is logging the error to either a database, a file or something. This will avoid all the #if DEBUGs all over the code. Please see this for more on logging.
This has additional benefits:
You will be able to see what your errors look like so when you go into production you will get the same information. If you do not have enough information, in the log, during development, it gives you a chance to change the error message and ensure the stack trace is there. This will be helpful when you go into production because now you have better errors.
Your code is cleaner
I have a simple C# application/game using SFML.Net that currently stops running / terminates within 1 or 2 seconds after being executed without any warning, exception, etc. whatsoever. Consider the following code:
public static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException);
--> The following two lines are run
Console.WriteLine("Hello");
Console.WriteLine("Please don't go...");
// Run the game
try
{
--> This line is reached
Game.Run();
}
catch (Exception e)
{
--> This line is never reached
Console.WriteLine(e.Message.ToString());
}
--> These lines are never reached
Console.WriteLine("Noone ever comes here, I feel so lonely... :(");
Console.ReadKey();
}
}
At this point you probably expect that something is wrong with the Game.Run() method. The odd thing is that the first line of the method is never reached according to the VS Debugger.
public static void Run()
{
try
{
--> Never reached
LoadContent();
// Do stuff here
while (window.IsOpen())
{
// The classic game loop
}
}
catch (Exception e)
{
--> Never reached
Console.WriteLine(e.Message.ToString());
Console.ReadKey();
}
}
My guess is that either:
You are getting an Access Violation Exception which cannot be caught.
OR
There is some other exception before you go into the Run method that is not handled. In order to verify that, make sure your debugger stops on first chance exceptions.
It would also be helpful if you specify:
How do you know that the first line is never reached? breakpoint? output?
What happens when you expect this function to be entered? does your application exist?
Are you debugging step by step?
My Guess is that the exception is being thrown by another thread. You cannot catch an exception thrown from another thread in the main thread. So your breakpoint in catch will never be hit. Btw did you try having a breakpoint in your UnhandledExceptionEventHandler method OnUnhandledException? That is where all unhandled exceptions go! Hope this helps.
You can get all called functions stack in your application until the termination point with the Runtime Flow tool (30 day trial, developed by me) and find what actually happens.
I came back to this after a couple of months and realized how silly my mistake was. Apparently unmanaged code debugging wasn't enabled by default (this was my first time using VS2012), and this exception was being thrown from the base C++ libs of SFML.
For those who don't know, to enable unmanaged debugging:
Project > Properties > Debug > Select "Enable unmanaged code debugging"
I've got something like this:
try
{
instance.SometimesThrowAnUnavoidableException(); // Visual Studio pauses the execution here due to the CustomException and I want to prevent that.
}
catch (CustomException exc)
{
// Handle an exception and go on.
}
anotherObject.AlsoThrowsCustomException(); // Here I want VS to catch the CustomException.
In another part of code I have multiple occurencies of situations where CustomException is thrown. I would like to force the Visual Studio to stop breaking on instance.SometimesThrowAnUnavoidableException() line cause it obscures the view of other places where I'm interested in breaking on CustomException.
I tried DebuggerNonUserCode but it is for a different purpose.
How to disable Visual Studio from catching particular exception only in a certain method?
You can use custom code to do this in two steps.
Disable automatic breaking on the CustomException exception.
Add a handler for the AppDomain.FirstChanceException event to your application. In the handler, if the actual exception is a CustomException, check the call stack to see if you actually want to break.
Use the Debugger.Break(); to cause Visual Studio to stop.
Here is some example code:
private void ListenForEvents()
{
AppDomain.CurrentDomain.FirstChanceException += HandleFirstChanceException;
}
private void HandleFirstChanceException(object sender, FirstChanceExceptionEventArgs e)
{
Exception ex = e.Exception as CustomException;
if (ex == null)
return;
// option 1
if (ex.TargetSite.Name == "SometimesThrowAnUnavoidableException")
return;
// option 2
if (ex.StackTrace.Contains("SometimesThrowAnUnavoidableException"))
return;
// examine ex if you hit this line
Debugger.Break();
}
In Visual Studio, go to debug->exceptions and turn off breaking for your CustomException by unchecking the appropriate checkbox, then set a breakpoint in the code (probably on the catch statement) on the places you actually want to break on.
If you want Visual Studio to stop breaking on all exceptions of a type, you have to configure the behavior from the Exceptions window.
Full instructions are here, but the gist is to go to the Debug menu and choose exceptions, then uncheck the items you dont want the debugger to break on.
I don't think there is a way to avoid a specific method using this technique, but maybe the better question is "why is this throwing an exception?"
You could add a set of #IF DEBUG pre-processor instructions to avoid running the problematic sections of code.
You can disable stepping altogether by placing the DebuggerStepThrough Attribute before the method.
As this disables stepping in the whole method, you may isolate the try-catch into a seperate one for debugging purposes.
I did not test, but it should not even break in that method when en exception is thrown. Give it try ;-)
See also this SO thread
You can't simply disable Visual Studio from stoping in a particular place of code. You can only prevent it to stop when particular type of exception is thrown but that will affect all places where such exception occurs.
Actually you can implement custom solution as suggested by 280Z28.
Background
In my utilities library (Shd.dll) I have a class called AsyncOperation. To put it simply, it's a base class for types that encapsulate a potentially long running operation, executes it on a background thread, and it supports pause/resume, cancellation and progress reporting. (It's like a BackgroundWorker, just knows more things.)
In the user code you can use it like this:
class MyOperation : AsyncOperation
{
public MyOperation() : base(null, AsyncOperationOptions.Cancelable | AsyncOperationOptions.Pausable) {}
protected override void RunOperation(AsyncOperationState operationState, object userState)
{
...
operationState.ThrowIfCancelled();
}
}
var op = new MyOperation();
op.Start();
...
op.Cancel();
operationState.ThrowIfCancelled() does exactly what its name suggests: if Cancel() was called earlier by another thread, it throws an internal exception (AsyncOperationCancelException), which is then handled by the AsyncOperation type, like this:
private void _DoExecute(object state)
{
// note that this method is already executed on the background thread
...
try
{
operationDelegate.DynamicInvoke(args); // this is where RunOperation() is called
}
catch(System.Reflection.TargetInvocationException tiex)
{
Exception inner = tiex.InnerException;
var cancelException = inner as AsyncOperationCancelException;
if(cancelException != null)
{
// the operation was cancelled
...
}
else
{
// the operation faulted
...
}
...
}
...
}
This works perfectly. Or so I thought for the past year, while I was using this in numerous scenarios.
The actual problem
I'm building a class that uses System.Net.WebClient to upload potentially large number of files via FTP. This class is built using the AsyncOperation base class as described above.
For accurate progress reports, I use WebClient.UploadFileAsync(), which complicates the code, but the relevant parts look like this:
private ManualResetEventSlim completedEvent = new ManualResetEventSlim(false);
private void WebClient_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
{
...
if (OperationState.IsCancellationRequested)
{
_GetCurrentWebClient().CancelAsync();
}
}
private void WebClient_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e)
{
...
_UploadNextFile();
}
private void _UploadNextFile()
{
if (OperationState.IsCancellationRequested || ...)
{
this.completedEvent.Set();
return;
}
...
}
protected override void RunOperation(AsyncOperationState operationState, object userState)
{
...
_UploadNextFile();
this.completedEvent.Wait();
operationState.ThrowIfCancelled(); // crash
...
}
As you can see, I marked the line where the crash occurs. What exactly happens is that when execution hits that line (I put a break point right over it, so I know this is the exact line), Visual Studio 2010 freezes for about 15 seconds, and then the next thing I see is the source code of AsyncOperationState.ThrowIfCancelled():
public void ThrowIfCancelled()
{
if(IsCancellationRequested)
{
throw new AsyncOperationCancelException();
}
} // this is the line the debugger highlights: "An exception of type AsyncOperationCancelException' occured in Shd.dll but was unhandled by user code."
I tried putting breakpoints to where the exception should have been caught, but the execution never reaches that catch {} block.
The other weird this is that at the end it also writes the following: "Function evaluation disabled because a previous function evaluation timed out." I Googled this problem, and tried everything that was suggested (disabled implicit property evaluation, removed all breakpoints), but nothing helped so far.
Here are two screenshots that illustrate the problem:
http://dl.dropbox.com/u/17147594/vsd1.png
http://dl.dropbox.com/u/17147594/vsd2.png
I'm using .NET 4.0. Any help would be very much appreciated.
When the Visual Studio debugger is attached to an application, it gets notified whenever an exception is thrown, before the running code gets the chance to handle it. This is called a first-chance exception, and VS can be configured to break execution when a certain exception type is thrown.
You can specify debugger behavior for each exception type separately using the Exceptions window (Debug menu). By default, all exceptions have the "User-unhandled" checkbox checked, meaning that only unhandled exceptions will break execution. Setting the "Thrown" checkbox for a certain exception type forces VS to break execution even if the exception will be handled, but only for that exception type (not for derived types). If a handler exists, once you resume execution (by pressing F5), the exception will be caught normally.
I would guess that your custom exception was added to the list of exceptions in the Exceptions window (which you can check by using the Find button inside the window).
[Edit]
According to my tests, it also happens when DynamicInvoke is used in .NET 4, regardless of the Exceptions window setting. Yesterday I was using VS2008 and I couldn't reproduce it, but it does seem like odd behavior now.
This is the test I tried (sorry for the brief formatting, but it's fairly simple):
Action<int> a = i => { throw new ArgumentException(); };
// When the following code is executed, VS2010 debugger
// will break on the `ArgumentException` above
// but ONLY if the target is .NET 4 (3.5 and lower don't break)
try { a.DynamicInvoke(5); }
catch (Exception ex)
{ }
// this doesn't break
try { a.Invoke(5); }
catch (Exception ex)
{ }
// neither does this
try { a(5); }
catch (Exception ex)
{ }
My only guess is that exception handling done inside InvokeMethodFast (which is an InternalCall method) has somehow changed. DynamicInvoke code has changed between versions 4 and prior, but there is nothing which would indicate why VS2010 debugger is unable to see that there is an exception handler inside that method call.
“a function evaluation has timed out”
You don't have a real problem, this is a debugger artifact. It is triggered by the way the debugger evaluates watch expressions. When you start a .NET program with the debugger attached, the program will have a dedicated thread, solely for use by the debugger. Whenever the debugger needs to evaluate a watch expression, it uses that thread to execute the expression code. The result is then displayed in the watch window.
Which works very well and gives the debugger a lot of capabilities. Including calling a method in your program when a breakpoint is active. Rather necessary, a lot of object values you'd be interested in are exposed as properties. Which are implemented as methods in the generated code.
That debugger thread can however cause trouble. An obvious case is where you try to evaluate a property that takes a lock. If you break execution at a stage where that lock is owned by another thread then the debugger thread is going to hit a brick wall. It trundles for a while, notices that the debugger thread isn't completing, then gives up and displays "a function evaluation has timed out" as the watch value. It also remembers that it failed, any watches you try later will produce "Function evaluation disabled because a previous function evaluation timed out". Necessarily so, the debugger thread is still stuck in a rut.
Similar kind of problem in your code. The probable scenario there is that the thread you need to get the operation completed got suspended by the debugger break. The only decent advice to give here is to be careful with your watch expressions.
If your try catch logic is running on a different thread than the code that actually throws the exception, then the catch block will never execute.
Consider the following sample:
class Program
{
static void Main(string[] args)
{
try
{
Thread thread = new Thread((s) =>
{
throw new Exception("Blah");
});
thread.Start();
}
catch (Exception ex)
{
Console.WriteLine("Exception caught: {0}", ex);
}
Console.ReadKey();
}
}
The catch block of course does not execute since the exception was thrown on a different thread.
I'm suspecting that you could be experiencing something similar. If you want your catch block to execute, it must be on the same thread that the error is being thrown on.
Good luck!