cgdb使用小结以及gdb调试死锁方法

"cgdb"

Posted by leiyiming on June 24, 2019

cgdb 使用小结


安装


源码下载地址 :https://cgdb.github.io/

安装依赖:

$ yum -y install ncurses-devel flex texinfo readline-devel

编译安装:

$ ./configure --prefix=/usr
$ make
$ sudo make install

使用文档:https://cgdb.github.io/docs/cgdb.pdf

用法


cgdb中窗口分为源码窗口和命令窗口,源码窗口能够在调试时实时显示当前位置,命令窗口则能够输入 gdb 命令来调试。

按下 esc 键,可进入源码窗口,此时可使用 vi 的命令来操控显示。

按下 i 键,可进入命令窗口,此时可输入 gdb 命令来进行调试。

gdb 命令


查看

  • info macro <macro> 查看宏定义。编译时需要设置 -g3 选项。
  • info break 查看断点信息
  • list <file>:<line-num> 查看源文件

断点

  • break <line-num> if <express> 设置条件断点
  • tbreak <line-num> 设置临时断点,只触发一次
  • ignore 1 30 跳过断点1的前30次触发
  • disable 禁用所有断点
  • disable <bp-num> 禁用指定断点
  • enable 启用所有断点
  • enable <bp-num> 启用指定断点
  • clear 清除当前行所有断点

变量值

  • watch <var> 如果变量被写,则程序暂停
  • rwatch <var> 如果变量被读取,则程序暂停
  • awatch <var> 如果变量被读或者被写,则程序暂停

控制

  • run <params> 启动调试,并附带参数
  • continue(c) 继续运行
  • next(n) 下一步,不进入函数
  • step(s) 下一步,如果是函数则,进入函数
  • quit(q) 退出gdb

多线程

set scheduler-locking off|on|step 在使用step或者continue命令调试当前被调试线程的时候,可以设置其他线程的表现。

  • off 不锁定任何线程,也就是所有线程都执行,这是默认值。
  • on 只有当前被调试程序会执行。
  • step 在单步的时候,除了next过一个函数的情况以外,只有当前线程会执行。

gdb 调试死锁方法


gdb相关命令

gcore <pid> # 生成死锁应用的coredump
gdb <bin> <core.1> # 进入gdb调试coredump
info threads # 显示所有线程信息
t <n> # 切换当前显示线程
bt # 显示当前线程所有堆栈
f <n> # 切换当前显示堆栈
p <var> # 打印变量值

调试过程

  1. 查看所有线程的堆栈,找出处于lock wait的线程
  2. 进入上述线程,然后打印 mutex 变量,其中 owner 属性代表的就是当前锁占有者的线程ID,注意在gdb中为LWP,并不是线程信息前面的序号。
  3. 进入占有者线程ID,比较两个线程阻塞位置,结合代码找出死锁。