Linux gdb use basics

Introduction to
GDB GDB (GNU Debugger) is a C/C++ program debugging tool under Linux. The program is debugged by executing corresponding commands on the command line. When using GDB, you only need to enter the gdb command or gdb filename in the shell (filename is Executable program file name) to enter the GDB debugging environment.

GDB mainly has the following functions:

  • Set breakpoint

  • Single step debugging

  • View the value of a variable

  • Dynamically change the execution environment of the program

  • Analyze the core file generated by the crashed program

GDB commonly used commands

Linux gdb use basics
Linux gdb use basics
Linux gdb use basics

Debug example 1
gdbtest.c:


#include <stdio.h>

int add(int start, int end)
{
    int i, sum;
    for(i=start; i<=end; i++)
        sum += i;
    return sum;
}

int main()
{
    int result;
    result = add(1, 10);
    printf("result=%d\n", result);

    return 0;
}

To compile, you need to add the -g parameter for GDB debugging:


$ gcc -o gdbtest gdbtest.c -g

This program is to calculate the sum of 1~10 computers. The correct result should output 55. Let's run the program first:


$ ./gdbtest
result=55

The program runs correctly on this computer, but there is a problem with the program. The sum variable in the add() function should be assigned an initial value of 0, otherwise it runs on other computers. If the variable is initialized with a random number, it will be calculated Wrong result. The reason why there is no error in this run should be that the variable is initialized to 0 by default, so the calculation is correct.

The following uses GDB to debug the executable program process:


$ gdb gdbtest

Output the following information:

GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from gdbtest...done.
(gdb)

First output some system information, (gdb) at the beginning of the last line is the command prompt, enter the start command to start debugging:


(gdb) start
Temporary breakpoint 1 at 0x67b: file gdbtest.c, line 14.
Starting program: /home/deeplearning/dcj/linuxCTest/GDBtest/gdbtest

Temporary breakpoint 1, main () at gdbtest.c:14
14          result = add(1, 10);
(gdb)

The program runs directly to the first substantial running statement at the main function, that is, the subroutine call on line 14. Here you can use the step command to step into the program of the statement:


(gdb) step
add (start=1, end=10) at gdbtest.c:6
6           for(i=start; i<=end; i++)
(gdb)

Continue to use the backtrace command to view the function call frame stack:


(gdb) backtrace
#0  add (start=1, end=10) at gdbtest.c:6
#1  0x000055555555468a in main () at gdbtest.c:14
(gdb)

It can be seen that the function add() is called by the main function, and the start and end parameter values ​​passed in by the main function. The stack frame number of the add() function is 0, and the stack frame number of the main function is 1.

You can continue to use the info locals command to view the value of the local variables in the add() function, or use the frame 1 command to first select the frame stack No. 1 where the main function is located, and then use the info locals command to view the value of the local variables in the main function:


(gdb) info locals
i = 0
sum = 0
(gdb) frame 1
#1  0x000055555555468a in main () at gdbtest.c:14
14          result = add(1, 10);
(gdb) info locals
result = 0
(gdb)

As you can see, the values ​​of the two local variables in the add() function are initialized to 0 by default, and the local variable result in the main function is also initialized to 0.

If the local variable is not initialized to 0 by default, you can modify the value of the variable through the set var command in the GDB environment and view the running effect. Since the program runs correctly on this computer, we now deliberately modify the initial value of sum to 100, and check the final running result:


(gdb) set var sum=100
No symbol "sum" in current context.
(gdb) frame 0
#0  add (start=1, end=10) at gdbtest.c:6
6           for(i=start; i<=end; i++)
(gdb) set var sum=100
(gdb) print sum
$1 = 100
(gdb) info locals
i = 0
sum = 100
(gdb) finish
Run till exit from #0  add (start=1, end=10) at gdbtest.c:6
0x000055555555468a in main () at gdbtest.c:14
14          result = add(1, 10);
Value returned is $2 = 155
(gdb)

Use set var sum=100 to modify the value of sum to 100, pay attention to switch to the frame stack environment where the sum variable is located, and then use the print or info locals command to view the modified result, and then use the finish command to make the program run automatically As a result, it can be seen that the final output result is 155, which is in line with expectations. Finally, you can use the quit command to exit the GDB environment:


(gdb) quit
A debugging session is active.

        Inferior 1 [process 31210] will be killed.

Quit anyway? (y or n) y
$

Type y to confirm and exit.

Debugging example 2
calculates the sum from 1 to n, gdbbreakpoint.c:


#include <stdio.h>

int main()
{
    int sum=0, i, data;
    while(1)
    {
        printf("please input a num(<100)\n");
        scanf("%d", &data);

        for(i=1; i<=data; i++)
            sum += i;

        printf("sum from 1 to %d is: %d\n", data, sum);
    }

    return 0;
}

Compile and run the test:


$ gcc -o gdbbreakpoint gdbbreakpoint.c -g
$ ./gdbbreakpoint
please input a num(<100)
2
sum from 1 to 2 is: 3
please input a num(<100)
3
sum from 1 to 3 is: 9
please input a num(<100)
4
sum from 1 to 4 is: 19
please input a num(<100)
^C

You can see that only the first calculation is correct, and all subsequent calculations are incorrect.

This time to debug the program by setting breakpoints. After entering the GDB environment, you can use the list command to view the source program first, and determine the breakpoints and line numbers needed:


(gdb) list
1       #include <stdio.h>
2
3       int main()
4       {
5           int sum=0, i, data;
6           while(1)
7           {
8               printf("please input a num(<100)\n");
9               scanf("%d", &data);
10
(gdb)
11              for(i=1; i<=data; i++)
12                  sum += i;
13
14              printf("sum from 1 to %d is: %d\n", data, sum);
15          }
16
17          return 0;
18      }
(gdb)

The list displays 10 lines at a time, and you can use the Enter key to continue the display. The for loop statement is on line 11. Use the break plus line number command to set a breakpoint:


(gdb) break 11
Breakpoint 1 at 0x73c: file gdbbreakpoint.c, line 11.
(gdb) info breakpoints
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000000073c in main
                                                   at gdbbreakpoint.c:11
(gdb)

Info breakpoints is also used here to view all the breakpoints currently set.

Then use the start command to start debugging:


(gdb) start
Temporary breakpoint 2 at 0x702: file gdbbreakpoint.c, line 4.
Starting program: /home/deeplearning/dcj/linuxCTest/GDBtest/gdbbreakpoint

Temporary breakpoint 2, main () at gdbbreakpoint.c:4
4       {
(gdb) continue
Continuing.
please input a num(<100)
2

Breakpoint 1, main () at gdbbreakpoint.c:11
11              for(i=1; i<=data; i++)
(gdb) info locals
sum = 0
i = 32767
data = 2
(gdb)

The program runs to the main function and pauses, and then continues to use the continue command to continue the program. Then the program prompts to enter a number, enter 2 first, and then the program executes to the breakpoint on line 11. At this time, use the info locals command to view the value of the local variable , I is a random number at this time (does not affect the subsequent results), sum and data are the expected results.

Continue to use the continue command, enter 3 this time, and use the info locals command again to view the value of the local variable at the breakpoint on line 11. It is found that the value of sum is not cleared after each loop, which leads to errors in the subsequent calculation results.


(gdb) continue
Continuing.
sum from 1 to 2 is: 3
please input a num(<100)
3

Breakpoint 1, main () at gdbbreakpoint.c:11
11              for(i=1; i<=data; i++)
(gdb) info locals
sum = 3
i = 3
data = 3
(gdb)

Find the reason, modify the source program manually, and assign sum to 0 at the beginning of the while loop body to fix the program problem.

reference:

"Proficient in Linux C Programming"-Cheng Guogang

"Linux C Programming Complete Decryption"-Yan Jing Wu Shukun

Guess you like

Origin blog.51cto.com/15060517/2641127