views:

1108

answers:

6

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.

+5  A: 

System.Diagnostics.Debugger.Break?

shahkalpesh
+1  A: 

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

System.Diagnostics.Debugger.Break();

but this did

System.Diagnostics.Debugger.Launch();
CheGueVerra
+14  A: 

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")]
void DebugBreak()
{
  if(System.Diagnostics.Debugger.IsAttached)
    System.Diagnostics.Debugger.Break();
}

Then add a call to it in your code.

ctacke
you can also use #if DEBUG ... #endif instead
Steven A. Lowe
Sure, but it's way more ugly than a conditional because you have to wrap every call to the method with the precompiler directive too.
ctacke
+1  A: 

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.

Lasse V. Karlsen
That's a trick worth mentioning. It's particularly helpful in identifying where the problem first occurs (and still get member state, not just exception stack trace?). But in this case I'd like the source to alert us to exceptions we aren't specifically expecting to occur and can't be set up for.
Rob Parker
A: 

Ahhh, thanks, shahkalpesh. System.Diagnostics.Debugger.Break() is a good start! That's what I was missing, under Debugger instead of Debug. It looks like that will interrupt and ask to attach a debugger, which I might want to avoid. But it looks like...

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

...might do what I'm looking for, as ctacke suggested. Debugger.Launch() might work for slightly different sitations, where you want a debugger if there wasn't one already.

Rob Parker
A: 

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

Jonathan C Dickinson
Cool trick. No good for system exceptions, of course, but we might try that with our own Exception types, conditional on a static member or two so we can turn it on and off, along with checking Debugger.IsAttached; one setting could Break()/Launch() even without IsAttached, another only if it is.
Rob Parker