GDB#
如何使用 GDB#
首先要做的就是将程序编译出来,然后,运行下面的命令进入 gdb 模式:
gdb <your_program>
参考文档:man gdb
。
本文使用的书写格式为:[c]ommand <required arg> (optional arg)
运行和调试程序#
# 设置断点
[b]reak <函数名 | 函数名:行号 | *内存地址>
# 反汇编
disassemble <函数名>
# 查看断点编号
[i]nfo [b]reak
# 删除断点
[d]elete <断点编号>
# 在条件为真时停在断点处
[condition] <断点编号> <C 语言描述的条件>
# 列出参数列表
[i]nfo (about)
(about) 可以是下面的任何一个:
[f]rame 当前栈帧,上一个栈帧,寄存器地址,参数列表,局部变量
[s]tack 栈轨迹,函数调用,参数列表
[r]egisters 每一个寄存器都保存了什么值
[b]reak 断点的编号的内存地址,断点位于什么函数内
[fu]nctions 函数签名
# 将指定文件加载到 gdb 中
[file] <可执行的文件名>
# 执行已加载的可执行程序
[r]un (arg1 arg2 ... argn)
# 继续执行源代码,停在下一个断点处
[c]ontinue
# 执行一行源代码(会跳转到函数调用内部)
[s]tep
# 执行一条 x86 指令(会跳转到函数调用内部)
[s]tep[i]
# 执行一行源代码(不会跳转到函数调用内部)
[n]ext
# 执行一条 x86 指令(不会跳转到函数调用内部)
[n]ext[i]
# 终止当前调试会话
[k]ill
# 打印栈轨迹,打印每个函数和它们的参数
[b]ack[t]race
info stack
where
# 退出 GDB
[q]uit
进入交互模式#
layout
命令允许我们调试源代码的同时,显示源代码。
# 未处于调试模式,进入 TUI 模式
gdb tui
# 已处于调试模式,进入 TUI 模式
tui enable
# 已处于 TUI 模式,展示下一个子窗口
layout next
# 已处于 TUI 模式,展示上一个子窗口
layout prev
# 已处于 TUI 模式,展示源代码
layout src
# 已处于 TUI 模式,展示汇编代码
layout asm
# 已处于 TUI 模式,同时展示源代码和汇编代码
layout split
# 已处于 TUI 模式,在展示源代码的同时,展示寄存器中的值
layout reg
# 已处于 TUI 模式,聚焦于下一个子窗口
focus next
# 已处于 TUI 模式,聚焦于上一个子窗口
focus prev
# 已处于 TUI 模式,聚焦于源代码子窗口
focus src
# 已处于 TUI 模式,聚焦于汇编代码子窗口
focus asm
# 已处于 TUI 模式,聚焦于寄存器子窗口
focus reg
# 已处于 TUI 模式,聚焦于命令行子窗口
focus cmd
# 已处于 TUI 模式,退出 TUI 模式
tui disable
# 已处于 TUI 模式,重新加载 TUI 模式
Ctrl + l
监视变量、寄存器和内存#
# 打印表达式的值
[p]rint <表达式>
表达式中可以包含变量名、*内存地址、$寄存器名、常量
# 打印表达式的值(16 进制表示)
[p]rint/x <表达式>
# 打印内存地址中的值
[x]/(number)(format)(unit_size) <内存地址>
number 从指定内存地址开始,连续的几个单位
format 打印格式,如果是 i 则不打印数字,而是打印指令
unit_size 数据大小 [b]ytes, [h]alfwords, [w]ords, [g]iants
# 反汇编某个函数
disassemble <函数名>
安装分屏工具 tmux#
sudo apt install tmux
更进一步地,我们需要掌握一些 常用的 tmux 命令:
# 创建 tmux 会话
tmux
# 纵向分屏
Ctrl + b, "
# 横向分屏
Ctrl + b, %
# 关闭当前分屏
Ctrl + b, x
# 切换分屏(按住 Ctrl + b 不放,再按方向键,可以调整窗口大小)
Ctrl + b, 方向键
小技巧#
如果在调试过程中修改了源代码,在下次运行 GDB 时使用 run (args)
可以重新定位到上次离开的地方。
使用 Ctrl + z
可以暂时将 GDB 挂起,然后使用命令 jobs
查看后台进程,使用 fg <编号>
恢复。