gdb笔记
摘要
命令总结
https://github.com/codeExploreHub/GDBDebug
连接
gdb连接进程分为两种(可能?)
使用gdb打开文件,然后开始运行
1 | gdb file |
使用gdb连接到一个已经在运行的进程
例如使用qemu模拟的一个qcow2内核镜像。这里需要注意的是,另外起的进程一般不会自动停住,等运行完连上去就晚了,所以需要控制启动后停止,例如qemu的参数就是-S,开机后暂停 CPU。
然后s等同 gdb tcp::1234,在本机监听 1234 端口作为 gdb server,让gdb能连上去
(其他参数都略过了)
1 | qemu-system-x86_64 -hda sys.qcow2 -S -s |
这边启动完成,另起终端打开gdb,连接到QEMU的调试端口
1 | sudo gdb |
如果说调试的镜像文件没有符号,但是你手头有一个有符号的文件symbol(?)可以为gdb调试镜像文件提供调试信息,那么可以在一开始用gdb打开它:
1 | (gdb) file ./symbol # 加载符号文件(如果之前没加载) |
或者
1 | gdb ./symbol |
解析:
symbol是带符号的elf,为gdb提供函数名、变量名、类型信息、行号等调试信息
gdb与qemu通过远程调试协议在端口1234进行连接
模拟器qemu实际执行的是要调试的内核镜像文件sys.qcow2
断点
函数断点。不讲
地址断点。形如:
1 | b *0xFFFFFFFF82890FBC |
删除断点
1 | (gdb) delete 3 # 删除编号为 3 的断点 |
禁用/启用断点
1 | (gdb) disable 3 # 禁用断点 3(暂时不用,但保留) |
条件断点
1 | (gdb) break *0xffffffff8289260e thread 2 if $r14d == 0x10 |
获取信息
查找find
基础命令形如
1 | find addr_start, addr_end, (内容) |
也可以是addr_start, +0x10000(地址范围
1 | (gdb) find /b 0xFFFFFFFF82891E7C, 0xFFFFFFFF82892000, 0xe8, 0x74, 0x54 |
x (examine)
基础命令形如
1 | x/(多少个)(格式) addr |
按指令显示
1 | (gdb) x/5i 0x12345680 |
按字节显示十六进制格式
1 | (gdb) x/5bx 0x12345680 |

查看寄存器
info或者p
查看所有寄存器
1 | (gdb) info all-registers |
查看特定寄存器
1 | # 查看rax寄存器的值 |
捕捉
watch
观察点一般用来观察某个表达式(变量也是一种表达式)的值是否有变化了,如果有变化,则马上停住。
catch
修改
set
改变某处的指令
1 | set {unsigned char}0xffffffff8280000 = 0xeb |
改变寄存器
1 | set $rax = 0x123456789abcdef0 |
线程
线程相关的命令
查看线程列表
1 | info thread |

切换线程
1 | thread 4 |
查看当前线程
1 | thread |
只在线程2上调试,其他线程冻结
1 | (gdb) thread 2 |
只影响当前线程的命令
1 | (gdb) next # 只执行当前线程的下一行 |
对所有线程生效的命令
输入 continue 时,所有线程都开始运行。哪个线程先遇到事件(断点、信号等),GDB 就会自动切换到那个线程并暂停。
按下Ctrl+C时,所有线程都会停止,但 GDB 会显示当前线程(通常是收到信号的线程)
断点(不指明线程时)对所有线程有效。GDB 默认在全停模式:当一个线程到达断点时,所有线程都会停止。
1 | (gdb) continue # 所有线程都会继续运行 |
单独对某个(些)线程执行命令-thread apply
不用切换线程的情况下对其他线程进行操作
1 | (gdb) thread apply all bt # 让所有线程执行 bt |
栈帧
1 | # 切换到指定帧(如 #2) |
其他
中止Ctrl+z
1 | # 方法1:恢复到前台(最常用) |
记录record
了解当前情况的方法
看不出来运行到哪里了怎么办?(运行太久了我都怀疑是不是已经跑空了)
在gdb界面按ctrl+c中止一下,程序收到 SIGINT(中断信号),冻结,这时可以进行操作。bt查看栈帧

gdb脚本
使用方法:
1 | gdb file |
pwndgb
breakrva:会自动给加基址偏移,在开了地址随机化的题目里可以用这个下断点
比如说基址是0x56555000,下断点,会自动计算0x56555000 + 0x152C = 0x5655652C:
1 | pwndbg> breakrva 0x152C |
rebase:还是加偏移的问题,加上rebase之后地址会自动加上vmmap里的基址
nearpc:会显示当前指令及其前后各 5-10 条指令,并自动标注跳转方向。