With continuous execution, you can quickly execute bug-free sections of code. To initiate continuous execution, either you can click the right mouse button on the line of code you want to debug or examine in more detail or you can position the cursor on this line and then press F7. Execution proceeds at full speed and pauses when it reaches the selected line.
You can also use a breakpoint to cause execution to pause at a specific line of code. CVW provides you with several types of breakpoints to control your application's execution. The sections that follow describe how to use breakpoints.
By specifying one or more lines as breakpoints, you can skip over the parts of the application that you don't want to examine. Execution of the application proceeds at full speed up to the first breakpoint, at which execution is interrupted; pressing F5 causes execution to continue up to the next breakpoint; and so on. You can set as many breakpoints as you want, provided that you have available memory.
Following are several ways to set breakpoints:
Double-click anywhere on the desired breakpoint line. The selected line is highlighted to show that it is a breakpoint. To remove the breakpoint, double-click on the line a second time.
Position the cursor anywhere on the line at which you want execution to pause. Press F9 to select the line as a breakpoint and to highlight it. Press F9 a second time to remove the breakpoint and highlighting.
Display the Set Breakpoint dialog box by choosing the Set Breakpoint command from the Watch menu. Select one of the breakpoint options that permits you to specify a line (location). The line on which the cursor rests is the default breakpoint line in the Location field. If this line is not the location you want, replace it by typing another line number in the Location field. When you type a new line number, make sure that you precede it with a period.
Your application can call the Windows DebugBreak function to interrupt execution and return control to CVW. When your application calls the DebugBreak function, execution may stop within the DebugBreak code rather than in your application. You may have to single-step out of the DebugBreak code and back into your application.
A breakpoint line must contain executable code. You cannot select a blank line, a comment line, or a declaration line (such as a variable declaration or a preprocessor statement) as a breakpoint.
To set a breakpoint on a multiline statement, you must position the cursor on the last line of the statement. If you try to set a breakpoint on any other line of the statement, CVW does not accept it.
If your compiler optimizes your code, some lines of code may be repositioned or reorganized for more efficient execution. These changes can prevent CVW from recognizing the corresponding lines of source code as breakpoints. Therefore, it is a good idea to disable optimization during development. You can restore optimization once debugging is completed.
A breakpoint can also be set at a function or an explicit address. To set a breakpoint at a function, simply enter the name of the function in the Set Breakpoint dialog box. To set a breakpoint at an address, enter the address in CS:IP form.
If any of the applications or DLLs you are debugging share names for certain window procedures (such as MainWndProc), you can refer by name only to the procedure that is defined in the first application or DLL.
You can remove a breakpoint by choosing the Edit Breakpoints command from the Watch menu or by selecting the breakpoint in the Source window and pressing F9. When your application pauses at a breakpoint, you can continue execution by pressing F5. You cannot remove a breakpoint set by an application calling the DebugBreak function.
Breakpoints are not limited to specific lines of code. CVW can also break execution when an expression changes value or reaches a particular value. Use one of the following methods to set a breakpoint value:
To interrupt execution when an expression changes value, type the name of the expression in the Expression field of the Set Breakpoint dialog box.
To interrupt execution when an expression reaches a particular value, use that value in the expression you type in the Expression field of the Set Breakpoint dialog box.
For example, if you want the application to pause when a variable named looptest equals 17, type the following in the Expression field:
looptest==17
The application pauses when this statement becomes true.
You can also use the Set Breakpoint dialog box to combine value breakpoints with line breakpoints so that execution stops at a specified line only if an expression has simultaneously changed value or reached a specified value.
For large variables (such as arrays and character strings), you can specify the number of bytes you want checked (up to 32K) in the Length field.
Note:
When a breakpoint is tied to a variable, CVW must check the variable's value after each machine instruction is executed. This computational overhead slows execution greatly. For maximum speed when debugging, either tie value breakpoints to specific lines or set value breakpoints only after you have reached the section of code that needs to be debugged.
You can also set a breakpoint on a Windows message or an entire class of Windows messages. By using this feature, you can track your application's response to user input and window-management messages.
To set a breakpoint on a Windows message or message class, type the wbm (Windows Breakpoint Message) command in the Watch window. The syntax for the command is:
wbm winproc msgname | msgclasses
The winproc parameter is the symbol name or address of an application's window procedure. The msgname parameter is the name of a Windows message, such as WM_PAINT. The msgclasses parameter is a string of characters that identify one or more classes of messages. If msgclasses is not specified, CVW traces all message classes. If it is specified, the classes are consistent with those defined in Microsoft Windows Spy (SPY.EXE); they are as follows:
Message class | Type of Windows message |
c | Clipboard |
d | DDE |
i | Initialization |
m | Mouse |
n | Input |
s | System |
w | Window management |
z | Nonclient |
For example, if your application is failing to refresh the client area of a window, you might set a breakpoint on the WM_PAINT message so that you can watch your application's behavior as it processes the message. The following command interrupts execution whenever the application's MainWndProc procedure receives a WM_PAINT message:
wbm MainWndProc WM_PAINT
This section shows how breakpoints can help you find the cause of a problem.
One of the most common bugs is a for loop that executes too many or too few times. If you set a breakpoint that encloses the loop statements, the application pauses after each iteration. You can then monitor the loop variable or critical program variables in the Watch or Local window to find the error in loop processing.
You can specify that a breakpoint is to be ignored. To set the number of times a breakpoint is to be ignored before execution is interrupted, perform the following steps:
1.From the Watch menu, choose Set Breakpoint.
2.In the Pass Count field of the Set Breakpoint dialog box, type the decimal number.
For example, suppose your application repeatedly calls a function to create a binary tree. You suspect that something goes wrong approximately halfway through the process. You could mark the line that calls the function as the breakpoint, then specify how many times this line is to be executed before execution pauses. Running the application creates a representative (but unfinished) tree structure that can be examined from the Watch window. You can then continue your analysis by using single-step execution, which is described in the next section.
Another programming error is assignment of the wrong value to a variable. If you enter a variable in the Expression field of the Set Breakpoint dialog box, execution is interrupted every time the variable changes value.
Breakpoints make it possible for you to interrupt execution of an application so that you can assign new values to variables. For example, if a limit value is set by a variable, you can change the value to see if it affects the application's execution. Similarly, you can pass a variety of values to a switch statement to see if they are correctly processed. This ability to alter variables provides an especially convenient way to test new functions without having to write a stand-alone test application.
When your application reaches a breakpoint and you change a variable, you might want to watch each step be executed while you check the value of that variable. This technique is called single-stepping.