I know what you’re thinking right now. Breakpoints? Seriously? What’s there to master about breakpoints? You hit F9 and then you stop at the line of code. If that’s what you’re thinking, this post is for you: read on 🙂
Visual Studio offers a fairly rich set of breakpoint types and actions that can make your debugging experience more comfortable and productive. We will look at four kinds of breakpoints in this post.
When defining a breakpoint, you can associate it with a condition (right-click the breakpoint and choose When Hit). In the condition you can use virtually any C# statement that you can evaluate in the Immediate window, including complex expressions. The debugger will then evaluate the expression every time the breakpoint is reached, and will break only if it evaluates to true.
Note that even though the breakpoint may only break infrequently, it still slows down the application because the debugger has to evaluate the expression when the application is paused before resuming it.
Breakpoints don’t have to break your application’s execution. In many cases, you just need to inspect the current value of some variable or expression and continue execution straight away. This doesn’t require changing the code to include trace statements: you can simply associate the breakpoint with a trace action that will display whatever message you’d like to the Visual Studio Output window. Again, you can display complex expressions.
You can set a breakpoint in a function even if you don’t have its source code. Simply go to Debug > New Breakpoint > Break at Function and specify the function name.
This is also available from the Call Stack window – simply click a frame and hit F9 to place a breakpoint on that function.
Data Breakpoints (C++ only)
You can use data breakpoints to stop the debugger when a particular memory location is modified. This super-powerful feature is very useful for multi-threaded applications and miscellaneous memory corruption scenarios, where a memory location is modified in an unexpected way. Unlike a source breakpoint, you don’t place the breakpoint on a line of code. Instead, you specify a memory location by using the Debug > New Breakpoint > New Data Breakpoint menu item.
Unfortunately, this feature works only for C/C++ applications. Managed objects move around the heap when they are promoted between generations or when heap compaction occurs, making them impossible to track.
As you have seen, by combining conditional breakpoints and tracepoints, you can obtain a trace of your application’s execution without adding any trace statements to your code or restarting your debugging session. By adding function breakpoints and data breakpoints, you can further improve the flexibility of your debugging work. Enjoy your Visual Studio breakpoints!
I am posting short links and updates on Twitter as well as on this blog. You can follow me: @goldshtn