GDB debugging learning (2): breakpoints

debugger (experimental subject)

      #include <stdio.h>
      int main(void)
      {
        int sum = 0, i = 0;
        char input[5];
        while (1) {
                      scanf("%s", input);
                      for (i = 0; input[i] != '\0'; i++)
                              sum = sum*10 + input[i] - '0';
                      printf("input=%d\n", sum);
        }
        return 0;
      }

The function of this program is: first read a string of numbers from the keyboard and store them in the character array input, then convert them into integers and store them in sum, and then print them out, and the cycle continues like this.

scanf("%s", input); The function of this call is to wait for the user to input a string and press Enter, scanf saves the first non-blank (non-blank, tab, newline) string in the input array, And automatically add '\0' at the end.

The next loop scans the string from left to right and adds each number to the result. For example, input "2345", the process of loop accumulation is (((0×10+2)×10+3)×10+ 4)×10+5=2345.

Note that the character '2' must be converted to the integer value 2 by subtracting the ASCII code of '0'. Let's compile and run the program to see what's wrong:

      $ gcc main.c -g -o main
      $ ./main
      123
      input=123
      234
      input=123234
   (按Ctrl+C组合键退出程序)
      $

This is the phenomenon again, the first time is right, the second time is wrong.

But in this program, we did not forget to assign an initial value, not only sum is assigned an initial value, but even i, which does not need to be assigned an initial value, is assigned an initial value. Readers first try to see if the code can see the cause of the error. Let's debug:

      $ gdb main
      ...
      (gdb) start
      Temporary breakpoint 1 at 0x804844d: file main.c, line 5.
      Starting program: /home/akaedu/main
      Temporary breakpoint 1, main () at main.c:5
      5               int sum = 0, i = 0;

With the previous experience, sum is listed as a key suspect. We can use the display command to display the current value of sum every time we stop, and then continue to go down:

      (gdb) display sum
      1: sum = 2637812
      (gdb) n
      9                     scanf("%s", input);
      1: sum = 0
      (gdb)(直接回车)
      123
      10                    for (i = 0; input[i] != '\0'; i++)
      1: sum = 0

The undisplay command can cancel the tracking display. The number of the variable sum is 1, and the undisplay 1 command can be used to cancel its tracking display. There should be no problem with this loop, because the above prints the correct result on the first input. If you don't want to go through this cycle step by step, you can use the break command (abbreviated as b) to set a breakpoint (Breakpoint) on line 9:

      (gdb) l
      5               int sum = 0, i = 0;
      6               char input[5];
      7
      8               while (1) {
      9                       scanf("%s", input);
      10                      for (i = 0; input[i] != '\0'; i++)
      11                              sum = sum*10 + input[i] - '0';
      12                      printf("input=%d\n", sum);
      13              }
      14              return 0;
      (gdb) b 9
      Breakpoint 2 at 0x804845d: file main.c, line 9.

The parameter of the break command can also be a function name, which means setting a breakpoint at the beginning of a certain function. Now use the continue command (abbreviated as c) to run continuously instead of single-step, and the program will automatically stop when it reaches the breakpoint, so that it can stop at the beginning of the next cycle:

      (gdb) c
      Continuing.
      input=123
      Breakpoint 2, main () at main.c:9
      9                       scanf("%s", input);
      1: sum = 123

Then enter a new string ready for conversion:

      (gdb) n
      234
      10                      for (i = 0; input[i] != '\0'; i++)
      1: sum = 123

The problem is exposed, the new conversion should start accumulating from 0 again, and the sum is now 123, because new loop did not zero the sum .

(So ​​this analysis problem is to have your own advanced thinking, and have an expected judgment on this result.)

It can be seen that breakpoints help to quickly skip codes without problems, and then slowly walk and analyze problematic codes. "Breakpoints plus single step" is the basic method of using a debugger.

As for where to set breakpoints, how to know which codes can be skipped and which codes should be walked slowly, it is also determined by analyzing and assuming the error phenomenon. In the past, when we used printf to print intermediate results, we also had to analyze where it should be. Insert printf, which intermediate results to print, the basic idea of ​​debugging is the same.

Multiple breakpoints can be set for one debugging, and the info command can be used to view the breakpoints that have been set:

      (gdb) b 12
      Breakpoint 3 at 0x80484b3: file main.c, line 12.
      (gdb) i breakpoints
      Num    Type          Disp Enb Address   What
      2      breakpoint    keep y   0x0804845d in main at main.c:9
        breakpoint already hit 1 time
      3      breakpoint    keep y   0x080484b3 in main at main.c:12

Each breakpoint has a number, which can be used to specify to delete a breakpoint:

      (gdb) delete breakpoints 2
      (gdb) i breakpoints
      Num    Type          Disp Enb Address   What
      3      breakpoint    keep y   0x080484b3 in main at main.c:12

Sometimes a breakpoint can be disabled instead of deleted if it is not used for the time being, so that it can be enabled directly when you want to use it in the future, without having to find out which line the breakpoint should be set in the code again:

      (gdb) disable breakpoints 3
      (gdb) i breakpoints
      Num    Type          Disp Enb Address   What
      3      breakpoint    keep n   0x080484b3 in main at main.c:12
      (gdb) enable 3
      (gdb) i breakpoints
      Num    Type          Disp Enb Address   What
      3      breakpoint    keep y   0x080484b3 in main at main.c:12
      (gdb) delete breakpoints
      Delete all breakpoints? (y or n) y
      (gdb) i breakpoints
      No breakpoints or watchpoints.

The breakpoint function of gdb is very flexible. You can also set the breakpoint to be activated when a certain condition is met. For example, we still set the breakpoint at the beginning of the loop, but only when the sum is not equal to 0. Then use the run command (abbreviated as r) Rerun continuously from the beginning of the program:

      (gdb) break 9 if sum != 0
      Breakpoint 4 at 0x804845d: file main.c, line 9.
      (gdb) i breakpoints
      Num    Type          Disp Enb Address   What
      4      breakpoint    keep y   0x0804845d in main at main.c:9
          stop only if sum != 0
      (gdb) r
      The program being debugged has been started already.
      Start it from the beginning? (y or n) y
      Starting program: /home/akaedu/main
      123
      input=123
      Breakpoint 4, main () at main.c:9
      9             scanf("%s", input);
      1: sum = 123

The result is that there is no interruption before the first scanf is executed, but it is interrupted the second time. Summarize the gdb commands used in this section, as shown in the following table.

insert image description here

Guess you like

Origin blog.csdn.net/weixin_45264425/article/details/132289249