【GDB调试-1】认识GDB

一、GDB是什么?

GDB是GUN项目的调试器,允许查看正在执行的程序里面在做什么,或者是程序崩溃的瞬间在做些什么。

GDB可以完成如下四种功能,在这些功能的基础上也可以做其他的事情:

  • 启动程序,按照指定的方式运行
  • 让程序在指定条件下停止
  • 当程序停止后查看发生了什么
  • 修正bug带来的影响从而去调试下一个问题

GDB可以在本地运行,也可以在远程运行(嵌入式平台,或者通过端口映射等方式进行远程访问),也可能是虚拟机里面运行,对于操作环境,覆盖了Unix和类Unix系统,Windows,Macos,我们主要接触到的桌面级操作系统就这三类,除此之外GDB也可以进行移植支持到其他系统,安装GCC交叉编译工具集的时候不包含GDB工具,可以通过不同类型的编译工具链对源码进行编译和安装。

二、GDB的安装

2.1 GDB可以解决哪些问题

工欲善其事,比先利其器,GDB绝对是调试bug的一把利器,下面是一些GDB能解决的问题:

  • 堆栈溢出
  • 调试死锁
  • 调试动态链接库
  • 利用core-dump文件解决bug
  • 远程调试
  • 对程序稳定性进行测试优化

GDB其本质上是对错误程序中出现的问题进行逆向工程,通过对问题的调试可以获得编程经验,从而应用到其他问题上的解决上。

除了GDB之外还有binutils工具,但是两者实现的功能不一样,使用binutils只能静态分析程序和程序产生的文件,GDB属于动态分析工具,在程序执行的时候可以直接进行调试。

2.2 GDB的安装

在CentOS上的安装:yum install gdb
在Ubuntu上的安装:apt-get install gdb
在MacOS上的安装:brew install gdb
在Windows上的安装:链接

三、GDB常用操作

功能示例
查看变量print var_name
执行下一行代码next
连续执行n行代码next n
单步执行,遇到函数会进入函数中step
强制当前函数返回return [value]
运行到当前函数返回finish
执行到目标行until line
跳转执行jump line
启动程序run
继续运行continue

四、GDB常用指令

4.1 GDB启动

4.1.1 启动方式:

  • gdb (直接启动)
  • gdb a.out(载入目标文件)
  • gdb a.out pid (动态链接)

4.1.2 GDB启动示例

1、带参数执行程序:

	gdb a.out
	set args arg1 arg2
	run

2、链接到目标进程执行:

	# 需要管理员权限
 	gdb
 	# 链接到目标文件后程序暂停
 	attach pid 
 	continue 

3、使用GDB调试stm32(此处需要安装st-util来连接stm32作为客户端,安装st-flash之后就会有st-util):

	# 在第一个终端中输入如下指令,运行之后会看到一个端口号,gdb进行连接的时候会使用到
	st-util
	# 在另一个终端中输入如下指令
	arm-none-eabi-gdb
	# 将gdb连接到st-util运行的端口
	target remote localhost:4242
	# 将调试文件加载到单片机
	load a.elf
	# 获取符号表         
	file a.elf
	run

4.2 断点管理

4.2.1 断点的分类

  • 软件断点: 通过使用非法指令进入特权模式实现(程序位于RAM中,软件实现,数量没有限制)
  • 硬件断点: 由硬件特性实现(数量有限,不在RAM中),在GDB中可以用hbreak设置硬件断点,用法和break一致
  • 数据断点: 由硬件特性实现(数量有限)

4.2.2 设置断点

  • 设置没有运行次数限制的断点
    • break 断点
    • b 断点
  • 设置只运行一次的临时断点
    • tbreak 断点
    • tb 断点
  • 通过文件名设置断点
    • b 文件名:行号
  • 通过函数名设置断点
    • b func
  • 设置条件断点
    • b 断点 条件
  • 通过偏移设置断点,当程序执行到某处停止后如果要对前面或者后面几行设置断点
    • b +偏移量
    • b -偏移量
  • 通过指令地址设置断点,在debug版本中包含符号信息,可以直接使用上面的方式设置断点,但是发布版本中一般没有符号信息,所以要先获得对应代码的地址然后再设置断点
    • 获取地址
      • p func
    • b *指令地址

4.2.3 查看断点

  • info breakpoints
  • info break
  • info b
  • i b

后面三个是缩写形式,会显示当前所有断点信息和对应编号

4.2.4 启用/禁用断点

  • 禁用断点:disable 断点编号
  • 启用断点:enable 断点编号
  • 启用一次断点:enable once 断点编号
  • 启用断点并删除(断点被命中后会被删除,类似临时断点):enable delete 断点编号
  • 启用断点并命中n次:enable count 次数 断点编号
  • 忽略前n次命中:ignore 断点编号 次数

有时候我们需要暂时禁用断点,但是后面又会继续使用,如果使用添加和删除断点这样非常麻烦,所以可以使用禁用断点来实现。

4.2.5 删除断点

  • 删除所有断点:delete
  • 删除指定断点:delete 断点编号
  • 删除指定范围内断点:delete 范围
    • delete 1-2
  • 删除指定函数的断点:clear 函数名
  • 删除指定行所在断点:clear 文件名:行号

4.3 GDB控制程序执行

4.3.1 跳过当前断点n次

  • continue 跳过次数

当程序执行到断点时候会停下来,使用continue可以让程序继续运行,但是如果加上一个数字则可以让当前断点在执行n次之后再停下,例如:continue 8 ,这条指令会再继续执行7次后停下来,这个8包含当前命中的这一次

4.3.2 继续执行到当前函数执行完

  • finish

如果用函数名设置了一个断点,在程序执行到停止后输入finish,将在函数执行完成后停下。

4.3.3 强制函数立即返回

  • return [value]

4.3.4 单步执行

  • step 或者 s

遇到的是函数会进入到函数中,遇到的不是函数就直接到下一行代码处。

4.3.5 逐过程执行

  • next 或者 n

遇到代码如果是函数会将整个函数执行完到下一行代码暂停,遇到的不是函数和单步执行一样。

4.3.6 执行到目标行

  • until line

4.3.7 跳转执行

  • jump line

4.4 变量/参数

4.4.1 查看参数

  • info args

4.4.2 查看/修改变量

  • print 数组名
  • print 变量
  • print *指针
  • set var 变量=值

4.4.3 自动显示变量

  • display 变量名(每次暂停之后自动显示变量的值)
  • display/格式 变量名(每次暂停之后按照指定格式自动显示变量的值,o(八进制),x(十六进制),d(十进制),t(二进制))。
  • info display(已经使用display设置自动显示的变量)
  • undisplay 变量名(取消自动变量的显示,没有变量名字代表取消除所有)
  • delete display 序号(删除变量的自动显示,没有序号代表删除所有)
  • disable display 序号(禁用自动显示,没有序号代表禁用所有,但是没有删除,info display还可以看到)
  • enable display 序号 (开启自动显示,没有序号代表启用所有变量的自动显示)

4.5 显示源代码

  • list 或者 l (可以显示断点前后5行代码,一共10行)
  • l- (显示从当前位置往前10行)
  • set listsize=显示的行数 (设置每次显示的行数)
  • list 函数名 (查看函数源码)

4.6 查看内存

  • x /格式 地址 (格式可以是如下参数:s(字符串),d(十进制),x(十六进制))

4.7 查看寄存器

  • info registers (查看所有整数运算的寄存器)
  • info all-registers (显示所有寄存器,包括浮点运算的寄存器)

在上述指令后面还可以加上寄存器名字显示指定的寄存器。

4.8 栈

当进行函数调用的时候会将寄存器和参数,临时变量等放入到栈中,所有这些消息称之为栈帧,每进行一次函数调用就会有一个新的栈帧,里面包含了程序运行时的状态,对于分析问题非常重要,在x86中依靠基址寄存器和栈顶指针维护栈空间,所有栈帧之间构成了一个链表。

  • backtrace 或者 bt (可以进行栈回溯,可以看出函数的调用顺序,参数,代码所在行,可以在指令后加上一个数字,这样可以显示更多的栈帧)
  • thread apply all bt 查看所有线程的栈帧
  • frame 栈帧序号(backtrace不能查看局部变量,由于每个函数的上下文不尽相同,通过切换栈帧可以查看局部变量,寄存器等信息)
  • info frame (查看栈帧的详细信息)
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咕咚.萌西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值