flow.
"Flow is a condition of deep, nearly meditative involvement." - Tom DeMarco

Fun with Breakpoints

Thursday, February 15, 2007 1:14 PM

Did you know that you can actually get some pretty advanced features with breakpoints inside of Visual Studio.  Some of these features will determine when the breakpoints are actually hit, some will determine how often the breakpoints are hit, and some will even determine what actually happens when the breakpoint is hit.

To get to these options all you have to do is add a breakpoint in code and then right-click the breakpoint itself.

Most of these are pretty straight forward.  Condtion, which is probably the one I use the most, lets you define a boolean condition using the code in your local scope to determine when the breakpoint will actually be hit.  This really comes in handy when you're tracking errors that only occur under certain conditions or certain states.  For example, you can only break when (firstTime == true) or ((i % 2) == 0) or (isDirty == true).

Hit Count is about as self-explanatory as it gets.  It works just like Condition in the sense that you can define statements using the code currently in scope but its centered more around iterative conditions.  Think about that last really tough boundary condition you tracked or the weird bug that shows up only on weird magic numbers and imagine how much faster you could have caught it if you'd been able to tell the breakpoint Hey, i only want to hear from you when (i == (Items.Count - 1)) or when (j == 56).

Filter works great for debugging multi threaded applications.  One of the big differences between this and the previous styles is we're not limited to our local code here.  This is more for breaking on a process-by-process or thread-by-thread basis.  So if you have named threads you can only break when the thread you want is executing the code and your conditional may look something like 'ThreadName = "BackgroundWorkerThread"'.

This brings us to When Hit, which is pretty much the reason I started this rambling in the first place.  You see, When Hit has two options: 1) you can print a message out to console relaying pertinent information like the stack trace, thread ID, etc or 2) you can run a macro.  I'll be honest, once the general "wow" factor of being able to trigger a macro wore off I couldn't really think of a single reason why I'd want to run a macro.  Then today, I had an epiphany.  Like most people, I'm sure, I tend to leave the exception settings on my debugger by and large alone when I'm not actually tracking a specific bug.  In case you don't know what I'm talking about, go to your Debug menu right now and choose Exceptions...

The window you see lets you choose whether you want the debugger to break whenever and exception is unhand led (the default) or to break whenever an exception occurs at all.  Having the debugger break on every single exception can be an absolute lifesaver when you're trying to locate a problem.  Especially if you're working on legacy code where the standard exception policy seemed to be just to swallow it and forget it.  This is the policy that says whenever something goes wrong in the app we just quietly shove it under the rug only to leave the user completely bewildered when their app suddenly stops responding, showing information, or generally doing anything at all.  However, having the debugger break on every single exception does slow you down significantly when you're just trying to get to the section of code you want to work on and a hundred exceptions in the data layer are being triggered just when the app is starting up. 

I usually set for a little of both and just set a breakpoint at the beginning of the section I want to start debugging and leave the default setting (only break on uncaught exceptions) on until I get there.  Then I switch it to "break on every exception" and debug happily away.  The only thing is that I have to remember to set a breakpoint at the end so I can go back and set the exceptions back to the default setting, otherwise I have to wade through an entire volley of exceptions next time I restart the app and it realizes I only have developer licenses, not runtime, for three different suites of third party controls, my database isn't production quality, etc....

Can you guess where I'm going yet?  I thought you could. 

Today it occurred to me that if I could just have a macro to launch that exception window to remind me to set the exceptions how I want them then I could just set that to run at my beginning and end breakpoints, freeing me of the responsibility of having to remember to turn them on and off appropriately.  Once I had my macro in place it was only a matter of setting it as the selected macro in the "When Breakpoint Is Hit" dialog.  One slight gotcha here though, be sure to uncheck "Continue execution" at the bottom of the dialog if you don't want your code just to take off again after you close the exception window, otherwise you won't be able to step manually through your code like you're used to after breakpoints.  Just think about it for a little bit, I'm sure you can come up with all kinds of interesting things to do with macros to help along your debugging.  Enjoy!

kick it on DotNetKicks.com

Feedback

 re: Fun with Breakpoints

Cool. I didn't realize that you could do that with VS. I use another IDE which has fully scriptable breakpoints. You can add condition to them and once they get hit you can do virtually anything. 2/19/2007 7:05 PM | Michael

# re: Fun with Breakpoints

Cool, glad it helped. What IDE do you use? I'm always on the lookout for the chance to play with another IDE. 2/19/2007 7:59 PM | Jeremy Jarrell

 re: Fun with Breakpoints

This was great. I've been using Visual Studio since the stone age and never even noticed conditional breakpoints. Boy, do I feel stupid :) 2/21/2007 11:52 AM | Boris Yeltsin

# re: Fun with Breakpoints

haha, i'm glad it helped. I wouldn't sweat it though, i'm 'pretty' sure that conditional breaks are a pretty recent addition. 2/22/2007 1:44 PM | Jeremy Jarrell

Post a comment





 

Please add 3 and 6 and type the answer here: