Use VC6.0 to C language program debugging the basic means to share

  • 2020-04-02 01:13:08
  • OfStack

(1) set fixed breakpoints or temporary breakpoints

A breakpoint is a line in a program that is specified and then paused, allowing the programmer to observe and analyze the program as it runs. These situations generally include:

Observe the current value of the variable in the program in the variable window (Varibles). The programmer observes these values to compare them to the expected value, and if they do not, the program running before the breakpoint must have a problem somewhere, so that the scope of failure can be narrowed. For example, the following program calculates cosine of x and shows that the result is 0.046414 no matter what x is input.


#include <stdio.h>
#include <math.h>
void main()
{
int  x;
printf("Please input x:");
scanf("% d", &x);
printf("cos(x)=%fn", cos(x));
}

In this program, if you do not see the problem -- it is difficult to see the problem when the program is long and complex -- you should use debugging to locate the fault.

Observe the value of the specified variable or expression in the Watch window. When there are many variables, it may be inconvenient to use the Varibles window, while the Watch window can be used to observe the changes of key variables purposefully and systematically.

Observe in the output window whether the current output of the program is consistent with the expected. Similarly, if not, the program running before this breakpoint must have a problem somewhere.

Observe the changes of data in Memory in the Memory window. In this window, you can directly query and modify the data of any address. For starters, it gives you a deeper understanding of how variables, arrays, structures, etc., use memory, and how arrays overstep bounds.

(5) observe the nesting of function calls in the Call Stack window. This window is useful for troubleshooting situations where function call relationships are complex or recursive.

(2) single-step execution program

Let the program be executed step by step (line by line), observe and analyze whether the execution process meets the requirements. For example, the expected function of the following program is to read in two Numbers (x and y) on the keyboard to determine whether x and y are equal. If they are equal, x=y will appear on the screen, and if they are not equal, x will appear < > Y. This is required, but what the program actually does is: whatever you type, it displays x=y and x < > Y, there must be something wrong with the program, but on the surface, it may not be able to find the problem. Using single step execution, it can locate the fault point and narrow the scope of view. For example, if you enter "2,3" in a single step and find that the values of x and y do become 2 and 3, then "printf("x=y\n") should not be executed. , but the step trace is found to be executed, so most of the problem is "if (x = y)".


#include <stdio.h>
void main()
{
int  x, y;
printf("Please input x, y:");
scanf("%d,%d", &x, &y);
if (x = y)
{
  printf("x=yn");
}
else;
{
  printf("x<>yn");
}
}

Step Over, Step Into, Step Out, Run to Cursor and other methods should be flexibly applied to improve debugging efficiency. It is recommended to remember and use shortcut keys of menu items such as "Step Over, Step Into, Step Out, Run to Cursor" during program debugging. It may be unfamiliar and slow at the beginning, but it will make you more efficient and efficient after a period of time.

(3) use assertions

An assertion is an inspection of a hypothetical condition (meaning that there is no action if the condition is true, otherwise it should be reported) that can quickly detect and locate software problems while automatically alerting the system to errors. Assertions can be used to locate problems that are hidden deep in the system and are extremely difficult to find by other means, thus reducing the time to locate software problems and improving the testability of the system. In practice, assertions can be designed flexibly according to the specific situation.
When using assertions, you must add:

# include < Assert. H >

Assertions can be used to confirm the parameters of the function. Example: if a function argument has a pointer, check it before using it to prevent others from using a null pointer as an argument when calling the function. The code is as follows:


int exam_fun( unsigned char *str )
{
    assert(str != NULL);  //Assert that "pointer is not null", if "null" (the assertion is not true) then an error is reported
    ... //other program code
}

Assertions can be used to confirm whether something should not have happened. Example: the following program runs with errors that are difficult to check and take a long time to figure out what's wrong. Therefore, it is recommended to analyze what should be the normal operation of the program, and whether there is an exception during the operation. For all (or key states) that should be normal, the use of assertions is likely to find the reason for the exception, and the debugging efficiency is very high. For this segment, we assert that the value of variable I should be "I > = 0 & & i. < "SIZE" is critical, but you can use assertions to check if it is possible to inadvertently modify (for example, if other variables are out of bounds) and go out of scope while running.


for (i=0; i<SIZE; i++)
{
    ... //other program code
assert(i>=0 && i<SIZE);  //Assert "normal value range of I", if the assertion is not true, it will report an error
array[i] = i;
    ... //other program code
}

When the assertion fails (an exception occurs), the system will immediately report an error, at this time can enter the program debugging state, check the running of the program.

(4) operation menu related to debugging: Build menu

Compile: shortcut key Ctrl+F7. Compile the source file that is currently in the source window to check for syntax errors or warnings, and if so, it will be displayed in the Output window.
Build: shortcut key F7. Connect the relevant files in the current project. If there is an error, it will also be displayed in the Output window.
Execute: shortcut Ctrl+F5. Run (execute) an executable (file) that has been compiled and connected successfully.
Start Debug: selecting this item brings up a submenu with several options for starting the debugger to run. For example, the Go option is used to execute the program from the current statement until a breakpoint is hit or the program is terminated. The Step Into option starts the program, and when a function call is encountered, it goes inside the function and starts again. The Run to Cursor option causes a program to pause execution when it runs to the line where the current mouse Cursor is (note that before using this option, set the mouse Cursor to a line where you want the program to pause). After the menu selection is executed, the debugger is started, and the Debug menu appears in the menu bar (instead of the Build menu).

(5) operation menu related to debugging: Debug menu

The Debug menu appears after the debugger is started (instead of the Build menu).
Go: shortcut key F5. Continue to run the program from the current statement until a breakpoint is hit or the program ends (the same functionality as the Build - Start Debug - Go option).
Restart: shortcut Ctrl+Shift+F5. Debug and execute the program from scratch (this is often necessary when you have made some changes to the program!). . When the item is selected, the system reloads the program into memory and abandons the current value of all variables (and starts again).
Stop Debugging: Shift+F5 for Debugging. Interrupt the current debugging process and return to normal editing status (note that the system will automatically close the debugger and reuse the Build menu to replace the Debug menu).
Step Into: F11. Step through the program, and when a function call statement is encountered, go inside that function and Step Into it from scratch (the same functionality as the Build - Start Debug - Step Into option).
Step Over: F10. Step through a program, but when you get to the function call statement, you don't go inside the function, but you go through the function in one step, and then you execute the statement after the function call statement.
Step Out: Shift+F11. Used in conjunction with "Step Into", this option allows you to return from inside the function (to the next statement in the function call statement) if you find that the Step debugging is no longer necessary after the execution enters the function and steps several steps.

Run to Cursor: Ctrl+F10. Causes the program to pause execution when running to the line where the current mouse cursor is (note that before using this option, set the mouse cursor to a line where you want the program to pause). In fact, a temporary breakpoint is set, the same as the Build - Start Debug - Run to Cursor option.

Insert/Remove Breakpoint: F9. This menu item does not appear on the Debug menu (on the context menu of the toolbar and the program document). It is listed here for the convenience of debugging. Also associated with fixed breakpoints are Alt+F9(all breakpoints in the hypervisor), Ctrl+F9(disable/enable the current breakpoint).


Related articles: