VS debugging skills + classic debugging cases

reject! ! superstitious debugging


1. Let’s take a look at the small concept first.

1.1 debug? What is debugging?

调试(debugging / debug),又称除错,是发现和减少计算机程序或电子仪器设备中程序错误的一个过程。基本步骤如下:

  1. DiscoverThe existence of program errors (programmers themselves, testers, users)
  2. Isolate and eliminate errorsLocate – Report bug (tester)
  3. Determine the cause of the errorThe reason
  4. Suggest ways to correct the errorSolution
  5. Correct the program errors and retest

1.2 What are debug version and release version?

debug - debug version: contains debugging information without any optimization, making it easier for programmers to debug programs.

release - Release version: various optimizations have been carried out to make the program optimal in terms of code size and running speed, so that users can use it well.

Notice:

  1. Relevant version information can be viewed by clicking in the folder and opening the exe file.
  2. The release version cannot be debugged step by step. The exe program of the release version of the same code will be larger than the debug version.
  3. To prepare for debugging in the Windows environment, select the "debug" environmentInsert image description here

2. Debugging skills in Windows environment

2.1 Use “shortcut keys” accurately

Fn - Secondary function key

  • F5 – Starts the program, often used to jump directly to the (logical) next breakpoint
  • ctrl+F5 – start execution (without debugging)
  • shift+F5 – Stop debugging
  • ctrl+shift+F5 – Restart debugging
  • F9 - Set/cancel breakpoints (can be anywhere in the program), often used in conjunction with F5, which allows the program to stop execution at the desired location and then execute step by step
  • ctrl+F9 – Stop breakpoint
  • ctrl+shift+F9 – delete all breakpoints
  • Tips:
    Conditional breakpoint (set the breakpoint position within the loop): Right-click on the breakpoint –> “Condition” –> Make corresponding adjustments< /span>
  • F10 – Process by process, one process at a time (one statement, one function call)
  • F11 - process by process, processing one statement at a time, and can enter the function (most commonly used)

2.2 Check the current information of the program during debugging

操作步骤:调试开始 ->“调试”->“窗口”->“自动窗口/局部变量/监视/内存/调用堆栈”->“ ”->“ ”

2.2.1 View the value of temporary variables

After debugging, use it to view the value of temporary variables

Operation steps: Start debugging ->"Debug"->"Window"->"Automatic window/local variables/monitoring/memory/call stack"->…

Monitoring: Manually set the variable information to be observed (As long as it is a legal expression, it can be monitored), it will not disappear when the program execution is separated. More convenient for debugging and observation.
Monitor the continuous array in the function (passing address): Enter -> "array name, number of elements to monitor" in the monitor

Automatic window: Automatically displays the current variable information that appears during program execution for observation.

Local variables: Automatically display local variable information of the context environment during program execution for observation.

2.2.2 View memory information

Memory: By entering the address/array name, you can observe the data actually stored in the memory and displayed in hexadecimal.

2.2.3 View call stack:

Call stack: Feedback the calling logic of the function.
(The stack here is the stack in the data structure)

2.2.3 View disassembly

After debugging, there is also a disassembly option in the right-click options.

2.2.3 View registers

Method 1: After debugging, select the register in the "Window"
Method 2: After debugging, enter the name of the register in the "Monitor" window to observe


3. !!!Classic debugging example!!!

Release a simple but weird code, as follows:

int main()
{
    
    
	int i = 0;
	int arr[10] = {
    
     1,2,3,4,5,6,7,8,9,10 };
	for (i = 0; i <= 12; i++)
	{
    
    
		arr[i] = 0;
		printf("hehe\n");
	}
	return 0;
}

Some students must be very confused. If there is a bug in this code, except for out-of-bound access that may not be detected by the compiler, what is so strange about it? The following is the interface after running in vs2019 for everyone to see:
Debugging results--infinite loop
No out-of-bounds access error was detected by the compiler, but the program entered an infinite loop...
So what exactly causes this invisible bug? We use debugging to troubleshoot the problem!

  • Start debugging, turn on monitoring, and enter all the elements that will appear in the "Name" field:
    Insert image description here
  • Under constant F10, the program reaches i=12 without any problems.
    Insert image description here
    Insert image description here
  • Until the program went through arr[i]=0
    Insert image description here
    the value of i was originally 12, but after the assignment of arr[i]=0;, it became 0. As a result, the value of i cannot be greater than 12, and the conditions cannot be met and the loop cannot be exited.
  • Sharp-eyed students have discovered that the values ​​of i and arr[12] in monitoring are the same. Even if the 12th loop has not been debugged, arr[12] changes with i. After contacting arr[12] to change the value of i, we add the addresses of i and arr[12] in the monitoring to see:
    Insert image description here
    The addresses are actually the same... This also explains why arr[i ] is always consistent with the value of i.
  • Debugging – This step of finding out the cause of the bug is complete.

这其实是一道笔试题,也在《C陷阱和缺陷》一书中写出来了,具体的原因,笔者用模仿笔试答题的方法为同学们解答:

  1. The usage habit of stack area memory is: use the space at the high address first, and then use the space at the low address
  2. ArrayAs the subscript increases, the address changes from low to high
  3. If there is an appropriate space between i and arr, using the array's out-of-bounds operation may overwrite i, which may lead to death The emergence of cycles
  4. The two spaces separated here are related tothe environment and the compiler
    Insert image description here

4. Summary

If you want to write excellent code, you must have good code logic, debuggability and maintainability. Common coding techniques are as follows:

  • Use assert
  • Try to use const
  • Develop good coding style
  • Add necessary comments
  • Avoid coding pitfalls

Guess you like

Origin blog.csdn.net/m0_67470729/article/details/126515115