使用GDB调试程序常用命令


GDB官网参考

一、启动程序

  • gdb [-tui] [execut_file] [| tee log_file],启动gdb
    -tui选项,启动可以直接将屏幕分成两个部分,上面显示源代码;
    tee命令可以将gdb调试时显示的所有信息输出到指定的文件中。
  • run,简写r:运行被调试的程序。如果此前没有下过断点,则执行完整个程序;如果有断点,则程序暂停在第一个可用断点处
  • start,开始调试,停在第一行代码处

二、改变控制流程

  • next,简写n:执行一行源程序代码,此行代码中的函数调用也一并执行,(gdb) n(gdb) n line-number
  • step,简写s:执行一行源程序代码,如果此行代码中有函数调用,则进入该函数,(gdb) s(gdb) s line-number
  • continue,简写c:继续执行被调试程序,直至下一个断点或程序结束,(gdb) c(gdb) c line-number
  • until [line-number],简写u [line-number]:可以指定程序运行到某一行停下来,如当前程序停在第10行,使用(gdb) u 23,则快速执行完中间代码,在23行停下来。
  • finish,执行完当前函数的所有语句,然后正常退出该函数
  • return,立即结束当前正在执行的函数,不再执行函数的后面语句,并返回。

三、查看表达式(变量)信息

  • print[/f|等] [var|ptr|addr],简写p[/f|等] [var]:显示指定变量的值,(gdb) p [var](gdb) p [&var](gdb) p [ptr](gdb) p [*ptr](gdb) p/x [var],参考自print详解
    其中f 表示显示方式, 可取如下值:
    x 按十六进制格式显示变量
    d 按十进制格式显示变量
    u 按十六进制格式显示无符号整型
    o 按八进制格式显示变量
    t 按二进制格式显示变量
    a 按十六进制格式显示变量
    c 按字符格式显示变量
    f 按浮点数格式显示变量

  • x /nfu <addr>,查看指定内存中存放的值,addr是个地址之,也可以用p *addr,但是一次只能查看一个字节,没有x好用
    1)n 表示要显示的内存单元的个数
    2)f同上面print指令中的f作用一样
    3)u表示一个地址单元的长度,可取如下值:
    b表示单字节
    h表示双字节
    w表示四字节
    g表示八字节

  • watch,一般来观察某个表达式(变量也是表达式)或内存地址的值是否发生了变化,如果发生变化则程序立即暂停,自动断点
    watch [exp|*addr],为exp设置一个观察点,如果其值变化,程序暂停,(gdb) watch a(gdb) watch *(int *) 0xffffff318c
    rwatch [exp|*addr]exp被读时,程序暂停
    awatch [exp|*addr]exp的值被读或被写时,程序暂停
    info watchpoints,列出当前所设置的所有观察点

  • display [var],设置想要跟踪的变量,自动显示
    info display,简写i display:显示所有跟踪变量
    undisplay [varnum|varnum1-varnum2],取消禁用指定编号/范围的变量跟踪显示,(gdb) undisplay 1
    disable display [varnum|varnum1-varnum2],禁用指定编号/范围的变量跟踪显示,(gdb) disable display 2-4
    enable display [varnum|varnum1-varnum2],启用指定编号/范围的变量跟踪显示
    delete display [varnum|varnum1-varnum2],删除指定编号/范围的变量跟踪显示

  • whatis [var]ptype [var],显示一个变量的类型

四、断点操作

  • break,简写b
    b,在下一条命令处停止运行
    b [函数名],在某个函数的开始处设置断点,(gdb) b main
    b [行号],在当前文件的指定行,(gdb) b 10
    b [文件名:函数名/行号],指定文件的指定行
    b [*address],在程序运行的内存地址处打断点
    以上任意b命令 [if <cond>]condtrue时,指定位置打断点,(gdb) b 10 if i==12

  • rbreak [REGEX|FILE:REGEX].REGEX是正则表达式,在所有文件或者指定文件符合正则表达式的函数上面打断点,如在所有函数上面打断点(gdb) rbreak .,在main.c文件中的所有函数上面打断电(gdb) rbreak main.c:.

  • ignore N COUNT,让N断点执行COUNT后停下,也就是前COUNT - 1次该断点不会起效

    (gdb) b lj_BC_JLOOP 
    Breakpoint 3 at 0x12003b020
    (gdb) ignore 3 316
    Will ignore next 316 crossings of breakpoint 3.
    
  • info breakpoints,简写i b:查看所有断点信息

  • disable [break-num],禁用某一个断点

  • enable [break-num],启用某一个断点

  • delete [break-num],简写d [break-num]:删除某一个断点

五、查看源码及其编译后的相关信息

  • list命令,简写l
    l,显示当前行后面的代码
    l [-],继当前显示向前再显示10行
    l [行号],显示10行,指定行号处于中间位置
    l [fun-name],显示指定函数名的上下文
  • backtrace,简写bt:查看当前程序的调用堆栈
    frame [num],简写f [num]:切换到其他堆栈处,通常与bt一起使用,(gdb) f 2
  • show args,查看发送给程序的参数(run后面跟的参数)
  • disas addr,查看addr处前后的反汇编代码

六、info系列

  • info registers,简写i r:查看除了浮点寄存器以外的寄存器
    info register [reg-name],简写i r [reg-name]:查看指定寄存器reg-name
    info all-registers,简写: 查看所有的寄存器包括浮点寄存器
    p $reg-name,可以查看寄存器的值
  • info break,简写i b:查看所有断点信息
  • info functions 查看所有的函数
  • info watchpoints,查看当前设置的所有观察点
  • info signals info handle,查看有哪些信号正在被gdb检测
  • info line [currLineNum],查看源代码在内存中的地址
  • info threads,查看线程信息,只会输出线程的简短信息,通常只是一层栈
    (gdb) info threads
      Id   Target Id                                  Frame 
    * 1    Thread 0xfff7c3ce70 (LWP 26956) "sysbench" main (argc=2, argv=0xffffff33b8) at sysbench.c:1405
    
  • info source,显示当前所在的源代码文件信息,文件名称,程序语言等
  • info frame,查看当前函数栈的一些详细信息
    (gdb) info frame
    Stack level 0, frame at 0xffffff2d40:
     pc = 0xaaaab00e4c in sb_histogram_print (sb_histogram.c:321); saved pc = 0xaaaab85948
     called by frame at 0xffffff2d40
     source language c.
     Arglist at 0xffffff2d40, args: h=0xaaaae46020
     Locals at 0xffffff2d40, Previous frame's sp is 0xffffff2d40
     Saved registers:
      gp at 0xffffff2d28, s8 at 0xffffff2d30, ra at 0xffffff2d38, pc at 0xffffff2d38
    

七、set系列

  • set var <assignment>,可以改变某个变量的值,如set var i = 10assignment的语法跟随调试语言本身(=:=),也可以使用set i=10,但可能会存在变量名(i)与gdb参数冲突的情况(printargs),所以最好还是用set var
  • set <reg-name = value>,修改该指定寄存器中的值,如set $pc = 100set $r1 = 0
  • set args <value1 value2 ...>,修改发送给程序的参数(run后面跟的参数)
  • set print <opt>,以指定的格式显示输出变量的值,在查看表达式(变量)信息时使用
    set print address [on|off],打开地址输出,当程序显示函数信息时,GDB会显出函数的参数地址
    set print array [on|off],打开数组显示,打开后当数组显示时,每个元素占一行,如果不打开的话,每个元素则以逗号分隔
    set print elements [num|unlimited],指定数组显示的最大长度,,当到达这个长度时,GDB就不再往下显示了。如果设置为0,则表示不限制
    set print null-stop [on|off],如果打开了这个选项,那么当显示字符串时,遇到结束符则停止显示。这个选项默认为off
    set print union [on|off],设置显示结构体时,是否显式其内的联合体数据。
    set print object [on|off],在C++中,如果一个对象指针指向其派生类,如果打开这个选项,GDB会自动按照虚方法调用的规则显示输出,如果关闭这个选项的话,GDB就不管虚函数表了
    set print pretty [on|off],控制结构体输出格式,打开则会以如下形式显示:
    $1 = {
          
          
    next = 0x0,
    flags = {
          
          
        sweet = 1,
        sour = 1
        },
    meat = 0x54 "Pork"
    }
    
  • set logging xxx组合可以将调试信息输出到指定文件,下面将所有线程栈信息输出到thread_info.txt文件中:
    set height 0	//设置在文件中的起始位置
    set logging file thread_info.txt	//指定输出文件
    set logging on	//此命令之后的所有调试信息将输出到thread_info.txt文件
    thread apply all bt	//查看所有线程栈信息,也可以是
    set logging off	//关闭到指定文件的输出
    

#### 八、其它常用命令
- `Enter键`,复制上一条命令
- `help [cmd]`,指定命令帮助提示,(gdb) help list
- `quit`,简写`q`,退出GDB调试环境
- `stack 20`,查看栈内20个值
- `vmmap`,查看映射状况 peda带有
- `readelf`,查看`elf`文件中各个段的起始地址 `peda`带有
- `parseheap`,显示堆状况 peda带有

猜你喜欢

转载自blog.csdn.net/qq_42570601/article/details/120672711