linux使用gdb调试程序
本文简单介绍 linux 平台上使用 gdb 工具进行程序调试的常用命令使用方法。在使用 gcc 编译程序时一般加上 -g 参数,对于 Makefile 或者 CMakefile 方式编译时,应当加上 --enable-debug 或者类似的编译参数,保证程序以 debug 模式进行编译,便于 gdb 调试。
1. gdb 挂载程序
(1)程序启动时挂载:
gdb myapp # 以 gdb 方式运行程序 myapp (gdb) b myfunc # 在 myfunc 函数上加断点 (gdb) run # 运行程序
(2)根据进程号进行挂载: 此方式用于对已经运行的程序进行调试。
gdb myapp 131618 # myapp 为程序路径,131618 为进程号 (gdb) b myfunc # 在 myfunc 函数上加断点 (gdb) c # 继续运行程序
2. 进入某个函数调用栈
frame 或 f 表示进入函数调用栈的层次
(gdb) frame n|f n
3. 设置断点
可以在函数名上设置断点,也可以在某个源码文件的某行代码上设置断点,如下:
b myfunc b main.c:123
查看断点:
info breakpoints|i breakpoints
删除断点:
delete breakpoints n 或 d n
使断点失效或生效:
disable breakpoints n disable n enable breakpoints n enable n
条件断点,满足指定条件时才会进入断点。
(gdb) break line-or-function if expr 例: (gdb) break 46 if testsize==100
4. gdb 跟踪子进程
跟踪子进程: set follow-fork-mode child
在子进程调用的函数或者代码行设置断点,如下所示:
(gdb) attach $parent_pid (gdb) b myfunc (gdb) set follow-fork-mode child (gdb) c
5. gdb 屏蔽信号
信号会导致程序频繁中断,如果信号不是调试的重点,则可以对信息进行屏蔽,如下:
屏蔽信号:handle SIGUSR1 noprint nostop 查看信号:info signal SIGUSR1
6. gdb 显示内存值
显示内存值:
命令: x /nfu
x 是 examine 的缩写
n 表示要显示的内存单元的个数
f 表示显示方式:
- x 按十六进制格式显示变量
- d 按十进制格式显示变量
- u 按十进制格式显示无符号整型
- o 按八进制格式显示变量
- t 按二进制格式显示变量
- a 按十六进制格式显示变量
- i 指令地址格式
- c 按字符格式显示变量
- f 按浮点数格式显示变量
- u 表示一个地址单元的长度
- b 单字节
- h 双字节
- w 四字节
- g 八字节
例子:
从内存地址address读取内容,显示一个4字节的十进制整数
x /1dw address
从内存地址address读取内容,显示4个单字节的十六进制整数
x /4bx address
7. 带参数的程序调试
gdb myapp set args 命令行参数 b func run
8. gdb 打印完整变量值
显示变量完整的字符串值:
set print elements 0 或者 set print elements unlimited
9. gdb 调用函数
commands 调用函数:
(gdb) b ExecutorRun (gdb) commands call elog_node_display(15, "plan", queryDesc->plannedstmt, 1) end
或者
(gdb) call printObject(queryDesc->plannedstmt)
10. gdb 多线程调试
i threads:显示所有线程,带*号的是当前线程
thread [num]:切换到某个线程