常用的GDB调试指令

目录

一、GDB 简介

 GDB是Linux下是调试程序的必备工具,相对于打印输出或打印日志,其能让我们检查程序的每一步执行,发现问题所在。要使用gdb调试可执行程序,gcc/g++编译时要加上参数-ggcc/g++ -g 编译时会加入调试信息,gdb 指令不能加;号。

  • gcc/g++ -g main.c 生成可调试的执行文件
  • gdb -p pid 调试某个进程 pid->进程号
  • gdb main.out 调试可执行文件
  • gdb -c core.xxx main.out 调试core文件

【回到目录】

二、GDB 指令速览

指令全称作用
$ gdb -tui启动gdb,分屏显示(上半部分源代码,下半部分gdb调试控制台),上下方向键滚动源代码,[Ctrl]n[Ctrl]p翻滚指令记录
$ gdb <app>启动gdb,并调试程序<app>
$ gdb -p <PID>启动gdb,并调试进程<PID>
$ gdb <app> <PID>启动gdb,调试进程号为<PID><app>可以使用:l / b / c / n / s / p
(gdb) help显示gdb help信息
(gdb) file <app>载入可执行程序<app>
(gdb) llist列出源码
(gdb) [Enter]直接回车,重复执行上一条指令
(gdb) b <line>break设置断点,在lines行处
(gdb) b <func>break设置断点,在函数func第一行处
(gdb) break x.cpp:21break设置断点,在源文件x.cpp的21行处
(gdb) info break查看断点信息
(gdb) delete删除所有断点
(gdb) delete <断点号N>删除N号断点
(gdb) rrun运行程序,可以加参数
(gdb) nnextstep over
(gdb) sstep in
(gdb) ccontinue继续执行到下一个可用断点或结束
(gdb) p <变量>print打印变量的值
(gdb) uuntil退出循环(光标可能需要停在循环的开头或结尾处)
(gdb) finish退出函数
(gdb) x/s <0x...地址>examine以字符串的形式显示该地址的值
(gdb) set var i=3设置变量i的值
(gdb) qquit退出gdb
(gdb) attach <PID>gdb<PID>进程,进程停在某个点
(gdb) detachgdb释放该进程,进程继续运行

【回到目录】

三、GDB 常用指令介绍

1、载入程序命令

  • file <app> 载入可执行程序<app>

2、设置断点

  • break 设置断点,可以简写为b (后面断点全部简写成b)
  • b 10 在源程序第10行,设置断点
  • b funcfunc函数入口处,,设置断点
  • b filename:linenum 在源文件filenamelinenum行,设置断点
  • b filename:function 在源文件filenamefunction函数的入口处,设置断点
  • b 类名::function或function(type,type) 在类classfunction函数的入口处,设置断点
  • b namespace::类名::function 在名称空间为namespace的类classfunction函数的入口处,设置断点

C++程序中可以使用class::functionfunction(type,type)格式来指定函数名。如果有名称空间,可以使用namespace::class::function或者function(type,type)格式来指定函数名。

3、设置观察点

  • watch 在指定变量/内存地址(表达式)expr设置一个watchpoint。一但expr值有变化时,将停住程序。
  • rwatchexpr被读时,停住程序。
  • awatchexpr被读或被写时,停住程序。
  • info watchpoints 列出当前所设置了的所有观察点。

在使用watch时步骤如下:

  1. 使用break在要观察的变量所在处设置断点;
  2. 使用run执行,直到断点;
  3. 使用watch设置观察点;
  4. 使用continue观察设置的观察点是否有变化。

4、断点管理

  • clear 清除所有的已定义的断点。
  • clear function 清除所有设置在函数上的断点。
  • clear linenum 清除所有设置在指定行上的断点。
  • clear filename:linenum 清除所有设置在指定文件:指定行上的断点。
  • delete [breakpoints] [range…] 删除指定的断点,breakpoints为断点号。如果不指定断点号,则表示删除所有的断点。range表示断点号的范围(如:3-7)。其简写命令为d
  • disable断点 disable了的断点,GDB不会删除,当你还需要时,enable即可,就好像回收站一样。
  • disable [breakpoints] [range…] disable所指定的断点,breakpoints为断点号。如果什么都不指定,表示disable所有的断点。简写命令是dis.
  • enable [breakpoints] [range…] enable所指定的断点,breakpoints为断点号。
  • enable [breakpoints] once [range…] enable所指定的断点一次,当程序停止后,该断点马上被GDB自动disable
  • enable [breakpoints] delete [range…] enable所指定的断点一次,当程序停止后,该断点马上被GDB自动删除。

5、查看源代码

  • list/l 显示当前行后面的源程序
  • list linenum 显示程序第linenum行的周围的源程序
  • list function 显示函数名为function的函数的源程序
  • list filename:linenum 显示指定文件指定行的前后代码
  • list filename:function 显示指定文件中的指定函数的前后代码
  • list first, last 显示从first行到last行之间的源代码
  • set listsize count 设置一次显示源代码的行数
  • show listsize 查看当前listsize的设置,默认为10

6、运行控制

  • run 运行程序,可简写为r

  • run [arg1] [arg2] 运行程序,并传递参数arg1arg2给程序

  • continue 继续执行程序,可简写为c

  • next 单步跟踪,函数调用当作一条简单语句执行,可简写为n

  • step 单步跟踪,函数调用会进入被调用函数体内,可简写为s

  • finish 退出函数,返回调用函数。打印函数返回时的堆栈地址和返回值及参数值等信息

  • until 在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体,可简写为u

  • nexti或ni 单步跟踪一条机器指令

    • stepi或si 单步跟踪一条机器指令,一条程序代码有可能由数条机器指令完成,stepi和nexti可以单步执行机器指令
  • backtrace/bt 显示程序中当前位置及到达当前位置的栈帧

  • info b 查看所有的断点信息

  • whatis 查看变量类型

  • info program 来查看程序的是否在运行,进程号被暂停的原因。

  • set var i=3 设置变量的值

7、查看变量

  • print/[fmt] <变量/字符串/表达式> 打印变量、字符串、表达式等的值,可简写为p
  • display/[fmt] <地址/表达式> 在程序停止时自动打印地址、表达式的值
  • examine/<n/f/u> <addr> 查看内存地址中的值,可简写为x
  • x/s <0x...地址> 以字符串的形式显示该地址的值

打印输出格式

GDB的数据显示格式:p/x 变量/字符串/表达式

  • x 按十六进制格式显示变量
  • d 按十进制格式显示变量
  • u 按十六进制格式显示无符号整型
  • o 按八进制格式显示变量
  • t 按二进制格式显示变量
  • a 按十六进制格式显示变量
  • c 按字符格式显示变量
  • f 按浮点数格式显示变量

examine命令格式

x/<n/f/u> <addr>

  • n,表示显示内存的长度,
  • f 表示显示的格式 GDB会根据变量的类型输出变量的值,也可以指定
    • s 按字符格式显示
    • i 按指令格式显示
    • x 按十六进制格式显示变量。
    • d 按十进制格式显示变量。
    • u 按十六进制格式显示无符号整型。
    • o 按八进制格式显示变量。
    • t 按二进制格式显示变量。
    • a 按十六进制格式显示变量。
    • c 按字符格式显示变量。
    • f 按浮点数格式显示变量。
  • u 表示从当前地址往后请求的地址单元的长度, GDB默认是w。
    • b 表示单字节,
    • h 表示双字节,
    • w 表示四字节,
    • g 表示八字节
  • <addr> 表示一个内存地址。

例如:

x/3uh 0x54320
表示:

  • 从内存地址0x54320读取内容,
  • 3表示三个单位
  • u表示按十六进制显示
  • h表示以双字节为一个单位

8、窗口分割命令

  • layout 用于分割窗口,可以一边查看代码,一边测试。
  • layout src 显示源代码窗口
  • layout asm 显示汇编窗口
  • layout regs 显示源代码/汇编和寄存器窗口
  • layout split 显示源代码和汇编窗口
  • layout next 显示下一个layout
  • layout prev 显示上一个layout
  • Ctrl + L 刷新窗口
  • Ctrl + x,再按1 单窗口模式,显示一个窗口
  • Ctrl + x,再按2 双窗口模式,显示两个窗口
  • Ctrl + x,再按a 回到传统模式,即退出layout,回到执行layout之前的调试窗口
  • focus cmd/src/asm/regs/next/prev 切换当前窗口
  • refresh 刷新所有窗口
  • tui reg next 显示下一组寄存器
  • tui reg system 显示系统寄存器
  • update 更新源代码窗口和当前执行点
  • winheight name +/- line 调整name窗口的高度
  • tabset nchar 设置tab为nchar个字符
  • tabstop nchar 设置tab为nchar个字符
  • tabstop 查看tab的设置

9、查看寄存器

  • info registers 查看寄存器信息
  • info all-registers 查看所有寄存器信息
  • info registers <regname> 查看指定寄存器信息
  • info registers <regname1> <regname2> 查看多个寄存器信息
  • info frame 查看当前栈帧信息
  • info args 查看当前栈帧的参数
  • info locals 查看当前栈帧的局部变量
  • info variables 查看当前栈帧的所有变量
  • info functions 查看当前栈帧的所有函数
  • info functions <function> 查看当前栈帧的指定函数
  • info functions <function1> <function2> 查看当前栈帧的多个函数

【回到目录】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值