关于 GDB 你需要知道的技巧

蓝月亮
发布于 2020-9-3 10:47
浏览
0收藏

gdb基本上是每个unix环境开发者都会使用的调试工具,使用gdb基本上可以按照自己的需求随心所欲的运行程序,可让被调试的程序在自己所指定的断点处停住,同时可以检查程序当前的状态,检查各种变量及寄存器的值,也可以动态的改变程序的执行环境。本期纯干货,无废话,准备好开始咯~

 

gdb调试的三种方法

  1. gdb filename:run开始、quit结束
  2. gdb attach pid:程序已经运行后,可使用attach跟踪进程,attach目标进程后,调试器会暂停下来,需要continue才继续,停止调试后使用detach命令分离调试器,quit结束
  3. 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函数处
  • (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系统调用。

标签
收藏
回复
举报
回复
    相关推荐