A breakpoint, if you haven't encountered one before, is just that – a point at which execution breaks and you can examine the program's state. Once the execution is stopped at a breakpoint, you can step into a function or step over a line, executing your program one line at a time to see how it's behaving. Clicking to the left-hand side of a line number in the Debug view lets you set or clear breakpoints. While stopped at a breakpoint, a yellow-colored arrow in the margin of the editor pane indicates the line of code that the processor is about to execute.
While at a breakpoint, several buttons appear above the call stack pane that let you control the program flow, which you can see in the following screenshot:
The buttons are defined as follows (again, numbered for easy reference):
- The green-colored Continue button, which continues execution at the line indicated by the arrow. You can also continue by pressing the F5 function key.
- The red-colored Stop button, which stops debugging altogether.
- The Step Over button, which executes the current line and advances to the next line before stopping again. You can step over one line by pressing F10.
- The Step Into button, which enters the next function to be called and stops again. You can step into a function by pressing F11.
- The Step Out button, which runs the remainder of the function in the current calling context before stopping again. You can step out of the current function by pressing Shift + F11.
- The instruction-wise button (looks like a little screen), which toggles the debugger between working a source line at a time and an assembly line at a time.
- There's also a menu of threads, so you can see which thread is running or has stopped.
For example, (in the previous screenshot) from line 7, if we step over line 8 (pressing F10) and then press F11, we'll end up inside our factorial function. At this point, if we step into the function again, we'll see the value for n change in the right-hand side column, and the arrow advance to point toward line 9 (again, as numbered in the screenshot). From here, we can debug the factorial function in several ways:
- We can examine the contents of a variable by looking at it in the right-hand side pane. If it's in a stack frame above the current calling frame, we can change call frames and see variables in a different call frame too.
- We can modify a variable by clicking on its value and entering a new value.
- With some debuggers, we can move the arrow to different lines in the calling function to skip one or more lines of code, or rewind the execution to rerun a segment of code again.
This last feature, which unfortunately doesn't work with the Microsoft command-line debugger, is especially powerful because we can step through a program, observe an error, modify variables to work around the cause of the error, and continue testing the code without needing to recompile it and rerun the executable. Or, I can skip a bit of the code that I know takes a while to run by substituting the new state in the variables in question and continuing from a new location in the current call frame.
Also, there are a number of other things that we can do, from how we debug the application to various ways in which we can view the state of the application when it's running. From the main Debug menu, we can do the following:
- Detach the debugger from a running process by selecting Detach from the Debug menu (this is handy if the debugger is slowing things down and we know that part of our code doesn't need to be debugged).
- Interrupt the program execution by stopping the execution and examining the current state by choosing Interrupt from the Debug menu (useful if our application seems caught in a long loop we weren't expecting and appears hung).
- While it is stopped, run to the line that the cursor is on by choosing Run to Line or pressing Ctrl + F10.
- While it is stopped, skip to the line that the cursor is on by choosing Jump to Line. Choosing Jump to Line lets you skip the lines of code between the current point and the target line.