Can .NET source code hard-code a debugging breakpo

2019-01-30 21:42发布

问题:

I'm looking for a way in .NET (2.0, C# in particular) for source code to trigger a debugging break as if a breakpoint was set at that point, without having to remember to set a specific breakpoint there in the debugger, and without interfering with production runtime.

Our code needs to swallow exceptions in production so we don't disrupt a client application that links to us, but I'm trying to set it up so that such errors will pop up to be analyzed if it happens to be running in a debugger, and otherwise will be safely ignored.

My attempt to use Debug.Assert(false) has been less than ideal, and I assume that Debug.Fail() would behave the same way. It should theoretically have no effect in production, and it does successfully stop when debugging, but by design there is (as far as I can tell) no way to continue execution if you want to ignore that error, like you could with an actual breakpoint, and like it would do in production where we swallow the error. It also apparently breaks evaluation of variable state because the debugger actually stops down in native system code and not in ours, so it's debugging help is limited. (Maybe I'm missing some way of getting back into things to look at the variables and so on where it happened. ???)

I was hoping for something like Debug.Break(), but it doesn't seem to exist (unless maybe in a later version of .NET?), and no other Debug methods seem applicable, either.

Update: While ctacke's answer is the best match for what I was looking for, I have since also discovered a trick with Debug.Assert()--when running in the debugger--Pause the debugger, go to the code for the Debug.Assert call pending (highlighted in green because it is down in the framework code) and hit Step-Out (shift-F11), then hit Ignore in the assert dialog box. This will leave the debugger paused upon the return of the assert (and able to continue execution as if it hadn't occurred, because it was ignored). There may be other ways to do much the same thing (does hitting Retry do this more directly?), but this way was intuitive.

回答1:

You probably are after something like this:

if(System.Diagnostics.Debugger.IsAttached)
  System.Diagnostics.Debugger.Break();

Of course that will still get compiled in a Release build. If you want it to behave more like the Debug object where the code simply doesn't exist in a Release build, then you could do something like this:

    // Conditional("Debug") means that calls to DebugBreak will only be
    // compiled when Debug is defined. DebugBreak will still be compiled
    // even in release mode, but the #if eliminates the code within it.
    // DebuggerHidden is so that, when the break happens, the call stack
    // is at the caller rather than inside of DebugBreak.
    [DebuggerHidden]
    [Conditional("DEBUG")] 
    void DebugBreak()
    {
        if(System.Diagnostics.Debugger.IsAttached)
            System.Diagnostics.Debugger.Break();
    }

Then add a call to it in your code.



回答2:

System.Diagnostics.Debugger.Break?



回答3:

I ran into a situation once where this didn't work

System.Diagnostics.Debugger.Break();

but this did

System.Diagnostics.Debugger.Launch();


回答4:

If you want to have only one line of code instead of 4, wrap

#if DEBUG
       if (Debugger.IsAttached)
            Debugger.Break();
#endif

into

public static class DebugHelper
{
    [DebuggerHidden]
    [Conditional("DEBUG")]
    public static void Stop()
    {
       if (Debugger.IsAttached)
            Debugger.Break();
    }
}

and use

DebugHelper.Stop();

DebuggerHiddenAttribute is added to prevent the debugger from stopping on the inner code of Stop method and from stepping into the method with F11.



回答5:

How about just configuring Visual Studio to pop up with the debugger even if you swallow it?

Do this:

  • Go to Debug->Exceptions...
  • Find the right exception, or add it if it's your own
  • Check the "Thrown" checkbox for the exception

This will stop Visual Studio on the location that exception is thrown, not just if it isn't handled.

You can see more information here.



回答6:

A nice trick I found is putting Debugger.Break() in the ctor of your Exception.



回答7:

In Visual Studio 2010, hitting Retry on a Debug.Assert dialog takes you to the failed debug assertion, just as if you had a breakpoint.