GDB quick reference: 一个很不错的cheatsheet
RMS的gdb tutorial
中文的gdb教程
1 最基本用法
最基本的gdb用法可以帮助你找到程序里哪里出现segment fault。首先你要在gcc编译的时候加上-ggdb选项。假定你的程序名叫foo,你可以用如下命令进入gdb开始program进行debug:
$ gdb foogdb会在你出现段错误的地方停下来,你会看到是哪个程序哪行语句出了问题.
2 Core Dump
发现了segment fault的话,还可以使用core dump。这样不但可以很方便的找到出问题的代码. 还可以多次重现这个错误。 首先使用以下的命令允许系统生成core文件.
$ ulimit -c unlimited然后运行你的代码,比如叫foo, 等到segment fault发生并异常退出以后, 你会发现在foo的同一个文件夹下多了一个名字类似core.1234这样的文件。这时候运行如下命令就可以重现案发现场了
$ gdb foo core.1234
3 普通用法
r [arglist]: (重新)运行程序
b [file:]line, b [file:]function: 设置断点在line或者function
c, continue: 继续运行程序
s, step: 单步执行, 进入函数
n, next: 单步执行, 不进入函数
finish: 执行完当前frame
kill: 终止当前程序
q, Ctrl-d: 退出gdb
p [expr]: 显示表达式expr. 比如var表示变量var的内容而 &var表示变量var的内存地址
bt: 显示当前调用栈(call stack)
set args [arglist]: 设置命令行参数,从而可以直接用r(run)来执行
4 断点(breakpoit)/观察点(watchpoint)设置与管理
b [file:]line, b [file:]function: 设置断点在line或者function
watch [expr]: 设置观察点,一旦表达式expr有变化就停下来. expr通常为一个变量或者内存地址
rwatch [expr]: 设置观察点,一旦被读就停下程序
awatch [expr]: 设置观察点,一旦被读或者被写都停下程序
比如你可以使用awatch *(long*)addr来监视内存地址addr是否被读或者被写
info breakpoints/watchpoints: 查看当前设置了的断点和观察点, info watchpoints是info breakpoints的alias
enable/disable/delete [n]: 激活/禁用/删除 编号为[n]的断点/观察点
5 程序栈
bt, backtrace: 显示当前调用栈(call stack),比如
(gdb) bt #0 0x000000010005ea07 in init (ctx=0x100622070, opts=@0x10060d078) at Utils.cpp:1678 #1 0x00000001000149ad in main (argc=3, argv=0x7fff5fbffb30) at main.cpp:591frame: 改变frame,比如
(gdb) frame 1 #2 0x8048414 in main (argc=1, argv=0xbffffaf4) at test.c:19 19 x = func1(x);info frame: 查看当前frame的信息
(gdb) info frame Stack level 2, frame at 0xbffffa8c: eip = 0x8048414 in main (test.c:19); saved eip 0x40037f5c called by frame at 0xbffffac8, caller of frame at 0xbffffa5c source language c. Arglist at 0xbffffa8c, args: argc=1, argv=0xbffffaf4 Locals at 0xbffffa8c, Previous frame's sp is 0x0 Saved registers: ebp at 0xbffffa8c, eip at 0xbffffa90info locals: 查看当前frame里的局部变量
(gdb) info locals x = 30 s = 0x8048484 "Hello World!\n"info args: 查看当前frame的调用参数
(gdb) info args argc = 1 argv = (char **) 0xbffffaf4
6 查看变量/函数, 改变变量值
如果有一个指针变量it指向一个struct item, 查看这个struct item的内存地址:
(gdb) p it $1 = (item *) 0x100700060查看这个struct的内容
(gdb) p *it $2 = { next = 0x100700000, prev = 0x0 }如果你有如下数组
int *array = (int *) malloc (len * sizeof (int));你可以这样来查看你的数组
p *array@len有时候你知道一段二进制代码所属的函数和偏移, 查这段对应的源代码:
list *myfunc+0x16
改变一个变量a的值为10
set variable a=10
7 查看内存
用命令"x /nfu <addr>"
n表示要显示的内存单元的个数
f表示显示方式, 可取如下值
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
i 指令地址格式
c 按字符格式显示变量。
f 按浮点数格式显示变量。
u表示一个地址单元的长度
b表示单字节,
h表示双字节,
w表示四字节,
g表示八字节
8 其他
info source: 查看当前frame对应的源文件信息
(gdb) info source Current source file is shared_ptr.hpp Compilation directory is /usr/local/include/boost/smart_ptr Located in /usr/local/include/boost/smart_ptr/shared_ptr.hpp Contains 712 lines. Source language is c++. Compiled with unknown debugging format. Does not include preprocessor macro info.info threads: 查看当前线程数目以及状态
(gdb) info threads Id Target Id Frame 3 process 35 thread 27 0x34e5 in sigpause () 2 process 35 thread 23 0x34e5 in sigpause () * 1 process 35 thread 13 main (argc=1, argv=0x7ffffff8) at threadtest.c:68