简体   繁体   中英

Can I enable/disable breaking on Exceptions programmatically?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM