关于 GDB 你需要知道的技巧
gdb基本上是每个unix环境开发者都会使用的调试工具,使用gdb基本上可以按照自己的需求随心所欲的运行程序,可让被调试的程序在自己所指定的断点处停住,同时可以检查程序当前的状态,检查各种变量及寄存器的值,也可以动态的改变程序的执行环境。本期纯干货,无废话,准备好开始咯~
gdb调试的三种方法
gdb filename:run开始、quit结束
gdb attach pid:程序已经运行后,可使用attach跟踪进程,attach目标进程后,调试器会暂停下来,需要continue才继续,停止调试后使用detach命令分离调试器,quit结束
gdb filename corename:默认不开启core,需要设置core文件大小,使用ulimit -a可查看core文件大小,使用ulimit -c [n]设置core文件最大n字节,使用ulimit -c unlimited表示修改为不限制大小。
自定义core文件名称
core文件的默认路径和名称为当前工作目录下生成的"core",通过如下方式可修改core的目录和文件名称:
echo "/root/test/core-%e-%p-%t" > /proc/sys/kernel/core_pattern
%p->pid
%u->uid
%g->gid
%s->signal
%t->timestamp
%h->hostname
%e->exectable name
常用命令
run(r): 运行一个程序
start: 执行程序,停在main函数处
continue(c): 让暂停的程序继续执行,continue默认遇到断点时候会暂停执行,可以使用continue n表示继续执行一定次数
next(n): 运行到下一行
step(s): 进入到调用函数内部
until(u): 运行到指定行停下来
finish(fi): 结束当前调用函数,到上一层函数调用处
return: 结束当前调用函数并返回指定值到上一层函数调用处
finish命令会执行函数到正常退出函数,return会立即结束当前函数并返回
jump(j): 执行流跳转到指定行或地址
print(p): 打印变量或寄存器值,也可以修改变量或寄存器值,默认显示有最大长度,设置set print element 0可设置将打印结果显示完整
backtrace(bt): 当前线程调用堆栈
bt n:显示栈顶的n个帧信息
bt -n: 显示栈底的n个帧信息
bt full: 显示栈中所有帧的所有信息:函数参数、本地变量等
frame(f): 切换到调用线程的制定堆栈
thread id: 切换到指定线程
break(b): 添加断点
tbradk: 添加临时断点(temporary)
rbreak [regex]在满足正则表达式的函数处添加断点
条件断点1:break [linenumber] if [condition]
条件断点2: 先break [linenumber]再condition [linenumber] [condition]
delete(del): 删除断点
enable: 启用某个断点
disable: 禁用某个断点
enable once [num]:断点只启用一次
捕获: catch和tcatch表示捕获xxx停止程序运行
catch syscall close 产生close系统调用后停止程序运行
display: 每次程序中断下来都会自动输出变量的值
delete display
info display
delete display id
watch: 监视某一变量或内存地址值是否发生变化,当变化时gdb就会停下
watch [expr/field]:发生变化时暂停执行
awatch [expr/field]:被访问或者发生变化时暂停执行
rwatch [expr/field]:被访问时暂停执行
watch expr thread [threadid]:监视某个线程的变量表达式
list(l): 显示源码
list + 向后看源码
list - 向前看源码
默认只显示10行代码,可以查看行数show listsize
可以设置行数set listsize [num]
list [first],[last]
list [function]
list [filename:function]
info: 查看断点线程等信息
ptype: 查看变量类型
whatis field 打印出field的结构定义
ptype field 更详细的打印field的类型
set variable [field]=[expression]改变变量的值
set $r0=[value] 改变寄存器的值
disassemble(dis): 查看汇编代码
show disassembly-flavor:显示反汇编指令格式
set disassembly-flavor intel 设置反汇编格式为intel格式
set args: 设置程序启动命令行参数
show args: 查看设置的命令行参数
info break:查看断点信息
info thread:查看线程信息
info sharedlibrary:显示加载的动态链接库信息
LWP:Light Weight Process轻量级进程
signal SIGSEGV: 可以使用signal SIGSEGV手动给程序发送信号
handle SIGSEGV 使用handle表示gdb调试时忽略某个信号
show scheduler-locking:显示当前线程scheduler-locking状态
set scheduler-locking on调试时将程序执行流锁定在当前线程,禁止上下文切换
set scheduler-locking off:不锁定任何线程,所有线程都执行
set scheduler-locking step: 阻止其它线程在当前线程单步调试时抢占当前线程,当next、continue、until、finish等其它线程才会执行
checkpoint搭配restart [id]: 相当于给在当前进程检查点加一个快照,适合调试难以复现的bug,预感将要发生bug前,添加个checkpoint
多线程调试
thread id 多线程时,默认是主线程,这里可以切换当前调试的线程为指定id的线程号
thread apply all [cmd] 所有线程执行命令
thread apply 1 2 3 [cmd] 1 2 3线程执行命令
thread apply 1 2 3 bt: 查看1 2 3线程堆栈信息
tui调试
tui调试是gdb自带的功能,ctrl+X+A可以开启TUI模式,开启TUI模式后默认会有两个窗口,上窗口是当前执行位置的代码,下窗口是gdb环境
cgdb
cgdb是一个更高级的调试工具,和gdb使用方式完全相同,默认就会开启tui功能查看代码
gdb调试原理
gdb调试原理是使用ptrace系统调用。
如果有任何问题,欢迎交流~
版权声明: 本文为 InfoQ 作者【程序喵大人】的原创文章。
原文链接:【http://xie.infoq.cn/article/c94aef7e3db8962ee306d33c5】。文章转载请联系作者。
评论