本文主要探讨gdb调试。
传入启动参数
gdb <exe>
set args <args>
r
调试运行进程
gdb <exe> + gdb attach <pid> 或 gdb --pid <pid>
detach 分离调试
q 退出调试
n 单步跳过
s 单步跳入
finish 退出当前函数
进入程序若r会杀死运行的程序,设置断点即可单步调试
断点
b file:line 文件某行加断点
b function 函数加断点
rb str 包含str的函数名加断点
b bp condition 条件断点(条件满足断点生效)
tb bp 设置临时断点
i bp 查看断点信息
disable b_num 禁止断点
enable b_num 使能断点
d b_num 删除断点
变量
i args 查看变量
p arg_name 查看变量
p arg_name = val 设置变量值
set print null-stop 设置字符串显示
set print pretty 设置结构体显示
set print array on 设置数组显示
sizeof,strlen,strcmp 内嵌函数
whatis var 查看变量或函数类型
ptype /r /o /m /t 查看变量或函数类型
/r: 显示typedef定义
/m: 不显示类方法
/M: 只显示类的方法
/t: 不显示类typedef
/o: 字段偏移量和大小
i variables var 显示变量名关键字定义文件
set print object on 显 示输出虚方法调用
内存
x /<n><fromat> address n地址个数 fromat显示方式
x /s addr_val 字符串显示地址中的值
x /d addr_val 十进制显示地址中的值
x /x addr_val 十六进制显示地址中的值
x /c addr_val 单字符串显示地址中的值
x /8d addr_val 显示addr_val起始的8个地址值,十进制方式显示
寄存器
i r 显示所有寄存器
i r rai 显示rdi寄存器
p $rip = addr 跳转执行
set var $pc = addr 跳转执行
函数传参依次存储的寄存器:rdi,rsi,rdx,rcx,r8,r9
源码
set listsize num 设置显示行数
l function 查看指定函数周围代码
l file:num 查看文件行周围代码
search str 搜索含str的行
forward-search str 前项搜索
reverse-search str 后项搜索
directory path 设置源代目录
调用栈
bt 查看栈信息
f num 切换栈帧
info f nnum 查看指定栈帧详细信息
线程
i thread 显示线程信息
t num 切换线程
t f str 查找含str的线程
t name 设置线程名
b thread num 为线程设置断点
thread apply num.. command 为多(一)个线程执行gdb命令
set print thread-events on|off 设置线程日志
show print thread-events 显示线程日志状态
jump
j function/line
跳转到指定行或函数定义处
跳转到指定位置执行,执行中存在断点则中断,无则继续执行
跳转不会更改堆栈帧和寄存器
skip(不参与调试,忽略,直接运行)
skip function 跳过函数
skip file filename 跳过文件
skip -gfi filename/* 跳过文件
函数调用
call function(argv) 调用函数
p function(argv) 调用函数并显示结果
观察点(断点)
观察点是变量/表达式,执行过程中中断打印
watch 写观察点
rwatch 读观察点
awtach 读写断点
i watch 显示观察点
delete/disable/enable num 删除/禁用/启用观察点
捕获
catch catch 捕捉catch
catch throw 捕捉throw
tatch catch 只捕获一次
堆栈溢出
call malloc_stats() 查看堆栈调用状态
call malloc_info(0,stdout) 查看堆栈调用状态
-fsanitize=address 编译选项,程序运行时检测到内存错误输出
core dump
某时刻(存活或崩溃)进程内存信息映射(内存信息,寄存器等信息)
gdb --pid num <exe> + generate-core-file 生成core dump文件
ulimit -c 设置core文件大小
/proc/sys/kernel/core_pattern 设置core文件名称
反向调试
record 打开记录
record stop 关闭记录
rn
rc
reverse-finish
制作发行版
gcc test.c -g -o test && strip test
strip去除符号表不能单独用于调试
进程
set follow-fork-mode child 调试子进程
set detach-on-fork off 调试父子进程
i inferiors 显示进程信息
inferior 2 切换进程
detach inferior 1
add-inferior <xe> 添加新的调试进程
remove-inferiors num 删除inferior,运行的不能删除
clone-inferior num 复制ninferior
detach inferior num 分离inferior,还可启动
kill inferior num kill掉inferior,还可启动
调试窗口
layout src 显示源码窗口
layour asm 显示汇编窗口
layout reg 显示寄存器窗口
layout split 切分窗口
focus src/asm/reg 切换窗口交点
iwin 查看当前拥有交点的窗口
ctrl+x+a 退出窗口模式
SHELL命令
! comman 执行shell命令
set logging on/off 启用/禁用结果输出
set logging file 设置输出文件
set logging overwrite 覆盖输出文件,默认为追加
断点执行命令
commands num num断点号,添加命令
cmd
cmd
end
save breakpoints filename 保存断定文件
source filename 读取断定文件
commands num num断点号,删除命令
end
补丁/破解
gdb --write <exe> 修改指定地址处值,永久生效
disassemble /mr function 将函数源码与汇编指令对应显示
0x0000000000001346 <+125>: 83 c0 01 add $0x1,%eax
set {unsigned char[3]}0x00000000000012f0 = {0x83, 0xc0, 0x11}
0x00000000000012f0 <+39>: 83 c0 11 add $0x11,%eax