You can't just change bugs by Meng-introduction to debugging

Author: digging everywhere Jiang Yucheng
link: https: //zhuanlan.zhihu.com/p/24128782
Source: know almost
copyrighted by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

"Every time you change a bug, you can only rely on Mongolian" This is a problem that many beginners of programming will encounter-this article will give a more simple introduction to how to debug. Although after reading this article, you may not be able to find out where the bug is all at once, but at least you can be targeted, and you won't have to just let it happen.

One of the most basic ideas for debugging a program is the dichotomy—similar to the binary search in an algorithm. For a program, most of the bugs are only concentrated in one submodule. We use the dichotomy, Continuously divide the program into two, troubleshooting and narrowing down the possible problems , so that the efficiency of debugging is much higher than that of the "random method" and the traversal method.

Here we use Visual Studio 2015 to debug a C++ program as an example-the methods for other languages ​​and environments are similar. As shown in the figure:
Then this program will explode when it is running: At
this time we need to use the divide and conquer method to judge which part of the program has the problem-here we use a method that seems "strength and miracle , Very simple and rude, but actually very effective, a wide range of methods: output method.
For example, for the above program, we need to determine which of the two for loops in the program is wrong-this time we can add some additional output statements as a mark.
For example, for the above program, we can add the following code on line 16:
cout<<"part 1 finished"<<endl;
Then the result of running is like this:
we can see that before the bombing, the program successfully output this line of mark-which means that for this example only, the code before the sixteenth line is no problem. Furthermore, if the program logic is more complicated, you can also output the value of certain variables to see if the value of this variable meets expectations.
At this time, we focus on the code after 16 lines-for such a small code block, we can already check the error directly with the naked eye. Students with good C++ basics can directly see that this is a typical access out-of-bounds error. The vector v1 now has only n elements, so v1[n] does not exist (array indexes in most languages ​​are left closed and right open Yes, the index of the last element of v1 is n-1), access to this element will naturally report an error.
Remove the equal sign of i<=n, and the program can run correctly at this time:
this method is not only suitable for CLI programs, but also GUI programs. For example, if you write WinForm in C#, it's like this:
MessageBox.Show("输出");
So you can output what you want-it can be a tag or the value of a specific variable.

Of course, this method of "making miracles vigorously" is just a stopgap measure-how to use the debugger will be introduced next.

First, let us clarify a concept-"breakpoint". The so-called "breakpoint" is one of the functions provided by the debugger, which allows your program to stop at a certain step and enter the break mode. At this time, the program will neither be terminated nor continue to execute-then you can use the debugger to control the execution of the program.
Here we still take C++ and Visual Studio 2015 as examples to illustrate- other languages ​​and other environments are similar (although the debugger may not be very easy to use), it is always the same .

Still the above program, click on the left side of the sixteenth line of code, as shown in the figure:
click to run, then enter the number, and then you will see the program stops at the breakpoint:
so we can get the same as before Conclusion-The procedure before the sixteenth line is no problem.
Next, click "Continue" to let the program execute directly to the next breakpoint (more than one breakpoint can be added), or end directly-at the same time, there are two buttons on the toolbar to control the program step by step Run it down so that you can more accurately identify where the bug is.
This article will talk about these first-about the more features of the debugger, and then introduce... The
debugger has three core functions: single step debugging, viewing the value of variables, and viewing the call stack . Next, we will introduce these three functions one by one.

First, let us look at the value of the variable-or the program above, click to enlarge, you can see that we have already seen the value of some variables in the "local variables" window below. For example, here we can see the value of n is 10.

Not only simple variables, Visual Studio also allows us to view the values ​​of more complex member variables-for example, here we create a vector, and then add the 10 numbers 0-9. At this time, we can directly click on the arrow next to it to expand v1: At
this time, we can see, after expanding, we can see the detailed information of v1-including capacity (capacity, here we can see the STL default allocation Slightly larger space), and the value of each element. And the array arr defined by ourselves cannot be accessed because there is no new yet.

Next, let us turn our attention to the upper toolbar:
Visual Studio provides two different buttons-step by step (on the right) and step by statement (on the left). The so-called "procedure by procedure" means that if the next statement to be executed is a function (or a member of an object), then the entire function is executed directly, and only the return result is viewed, while "statement by statement" refers to directly entering the function / Subject's body. Therefore, it should be noted that if a statement uses certain methods or operator overloads of the standard library, then do not use "statement by statement", otherwise it will get into the code of the standard library, which is meaningless.
As you can see, this is drilled into the definition of the new operator provided by the VC library.

Flexible use of single-step debugging feature that allows you even can not be seen directly with the naked eye, you can also use "awkward" to find bug-- For example, for this example, we use single-step debugging, as shown below:
Now The loop body has been executed for 10 rounds, now i=9, we continue to execute:
now i has become 10, the next step is to perform the assignment operation, and then go one step further:
now we can accurately locate where it is If one step is wrong, it will naturally be easier to modify.
In addition, when beginners use VS to do exercises, there is often a problem-after the VS program is executed, the command line window disappears, and the output result is not visible. Using the debugging function, we can also have a very simple and no additional effect to solve this problem: hit the breakpoint on return 0;-in this way, when the main part of the program is completely executed, it will It automatically stops at the last step before the end (return 0;), and then you can see the complete output result.

Finally, let's take a look at the use of the function call stack viewing function-first, you need to understand what a function call stack is. I will not talk nonsense here. If you don't understand, go directly to my class: C++ Programming-Course- Jie Suan Ke

Let's use this picture directly as an example-this is a function that uses recursion to find factorial: the
code is as follows-we directly stop at the fac(1) step:
pay attention to the call stack window in the lower right corner, we can see that the call is now There is only one main() function in the stack. Then continue to execute down and select "statement by statement":

we can see that one fac has been put into the call stack-continue to go down:
another one has been put in-then it is time to return:

It's clear at a glance.

These are the three main functions of the debugger-for other languages ​​and other environments (such as gdb), although the specific details are different, the core ideas are the same and never change.
The above is the main content of this article-I am ashamed, made a small contribution, thank you all.

Guess you like

Origin blog.csdn.net/qq_26751117/article/details/53442861