Introductory sharing of debugging GDB debugging method in Linux system

This article explains how to use GDB to debug Linux applications. The following is  hellowld.c an example to introduce the introduction of GDB debugging:

Write code

#include <stdio.h>

int main(int argc, char **argv)
{
    int i;
    int result = 0;

    if(1 >= argc)
    {
        printf("Helloworld.\n");
    }
    printf("Hello World %s!\n",argv[1]);

    for(i = 1; i <= 100; i++)  {
        result += i;
    }

    printf("result = %d\n", result );

    return 0;
}

Add  -g parameters when compiling:

gcc helloworld.c -o hellowrld -g

start debugging

$ gdb helloWorld
GNU gdb (GDB) Red Hat Enterprise Linux 8.2-12.el8
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-redhat-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 helloworld...done.
(gdb) run                  <----------------------------- 不带参数运行
Starting program: /home/zhuzhg/helloworld
Missing separate debuginfos, use: yum debuginfo-install glibc-2.28-101.el8.x86_64
helloworld.
result = 5050
[Inferior 1 (process 1069013) exited normally]
(gdb) run China            <----------------------------- 带参数运行
Starting program: /home/zhuzhg/helloworld China
Hello World China!
result = 5050
[Inferior 1 (process 1071086) exited normally]
(gdb)

breakpoint

set breakpoint

  • File line number breakpoint:break hellowrld.c:9

  • Function breakpoint:break main

  • Conditional breakpoint:break helloworld.c:17 if c == 10

  • Temporary breakpoint, assuming that a breakpoint somewhere only takes effect once, you can set a temporary breakpoint so that it will no longer exist after the breakpoint:tbreak helleworld.c:9

  • Disable or enable breakpoints:

  disable                 # 禁用所有断点
  disable bnum            # 禁用标号为bnum的断点
  enable                  # 启用所有断点
  enable bnum             # 启用标号为bnum的断点
  enable delete bnum      # 启动标号为bnum的断点,并且在此之后删除该断点
  • Breakpoint cleared:

  clear                   # 删除当前行所有breakpoints
  clear function          # 删除函数名为function处的断点
  clear filename:function # 删除文件filename中函数function处的断点
  clear lineNum           # 删除行号为lineNum处的断点
  clear f:lename:lineNum  # 删除文件filename中行号为lineNum处的断点
  delete                  # 删除所有breakpoints,watchpoints和catchpoints
  delete bnum             # 删除断点号为bnum的断点

variable view

  • Variable viewing:  The most common use is to use print (which can be abbreviated as p) to print variable content.

    Take the above program as an example:

    gdb helloworld
    break helloworld.c:17 if i == 0
    (gdb) run
    Starting program: /home/book/helloworld
    helloworld.
    
    Breakpoint 2, main (argc=1, argv=0x7fffffffdca8) at helloworld.c:17
    17            result += i;
    (gdb) print i                <------------------ 查看变量 i 当前的值
    $1 = 10
    (gdb) print result           <------------------ 查看变量 result 当前的值
    $2 = 45
    (gdb) print argc             <------------------ 查看变量 argc 当前的值
    $3 = 1
    (gdb) print str
    $4 = 0x4006c8 "Hello World" <------------------ 查看变量 str 当前的值
    
  • Check memory:  examine (abbreviated as x) can be used to check the value in the memory address. The syntax is as follows:

    x/[n][f][u] addr
    

    in:

    Common unit types are as follows:

    Example:

    (gdb) x/4b str
    0x4006c8:    01001000    01100101    01101100    01101100
    

    It can be seen that the four bytes of the variable str are all printed in binary.

    • b bytes

    • h half word, double byte

    • w word, that is, four bytes

    • g eight bytes

    • n indicates the number of memory cells to display, the default value is 1

    • f indicates the format to be printed, and the format control characters have been mentioned earlier

    • u The length of the unit to be printed

    • addr memory address

  • View register contents: info registers

    ra             0x3ff7ef2282     0x3ff7ef2282 <__libc_start_main+160>
    sp             0x3ffffffaa0     0x3ffffffaa0
    gp             0x2aaaaac800     0x2aaaaac800
    tp             0x3ff7fdd250     0x3ff7fdd250
    t0             0x3ff7ed60b0     274742468784
    t1             0x3ff7ef21e2     274742583778
    t2             0x2aaaaac4f0     183251944688
    fp             0x3ffffffab0     0x3ffffffab0
    s1             0x0      0
    a0             0x1      1
    a1             0x3ffffffc28     274877905960
    a2             0x3ffffffc38     274877905976
    a3             0x0      0
    a4             0x3ffffffad8     274877905624
    a5             0x0      0
    a6             0x3ff7fd88a8     274743527592
    (内容过多未显示完全)
    

single step debugging

  • Step through -next:

    The next command (can be abbreviated as n) is used to continue to execute the next statement after the program is stopped, assuming that debugging has been started, and stop at line 12, if you want to continue execution, use n to execute the next statement, if later Keep up with the number num, it means that the command is executed num times, and the effect of continuing to execute n lines is achieved:

   gdb helloworld                     <------------------------------- 加载程序
   (gdb) break helloworld.c:18        <------------------------------- 设置断点
   (gdb) run                          <------------------------------- 启动调试
   The program being debugged has been started already.
   Start it from the beginning? (y or n) y
   Starting program: /home/book/helloworld
   Helleo World.
   
   Breakpoint 2, main (argc=1, argv=0x7fffffffdca8) at helloworld.c:18         <-------- 程序在 18 行暂停
   18            result += i;
   Breakpoint 2, main (argc=1, argv=0x7fffffffdca8) at helloworld.c:18
   18            result += i;
   (gdb) next                                    <--------  单步执行
   
   17        for(i = 1; i <= 100; i++)  {
   
   Breakpoint 2, main (argc=1, argv=0x7fffffffdca8) at helloworld.c:18
   18            result += i;
   (gdb) next 2                                  <--------  执行两次
   
   Breakpoint 2, main (argc=1, argv=0x7fffffffdca8) at helloworld.c:18
   18            result += i;
  • Step into -step:

    If we want to track the internal situation of the function, we can use the step command (which can be abbreviated as s), which can single-step track to the inside of the function, but only if the function has debugging information and source code information.

  • Breakpoint continue -continue:

    The continue command (can be abbreviated as c), it will continue to execute the program until it encounters the breakpoint again.

Guess you like

Origin blog.csdn.net/weixin_41114301/article/details/132646596