本清单提供了对 GDB 的入门简要概述,以及 GDB
常用示例,完整文档参阅 Debugging with gdb,该文档最后有 GDB index
,可以快速查找命令。
[]
内为命令缩写
命令 [缩写] | 说明 |
---|---|
help[h] | 查看命令帮助。如 help run |
run[r] | 运行程序。可搭配参数使用 |
start | 运行程序,停在第一条执行语句。可搭配参数使用 |
list[l] | 查看程序源码 |
break[b] | 设置断点。可指定文件名、函数名和行号等参数来设置断点 |
watch | 设置监视点。当监视的变量发生更改时,程序会被中断 |
delete | 删除断点等。可用于删除断点、监视点、display 等 |
continue[c] | 继续执行程序。让程序继续执行,到下一个断点或程序结束 |
next[n] | 单步执行程序,跳过函数调用 |
step[s] | 单步执行程序,进入函数调用 |
finish | 结束当前函数。返回到函数调用点 |
kill | 杀死当前的调试进程 |
backtrace[bt] | 查看函数调用栈。它会打印出当前的函数调用栈 |
frame[fr] | 切换栈帧。以查看该栈帧中的局部变量和参数等 |
info | 查看程序状态信息。例如断点、寄存器、线程、局部变量等 |
show | 查看 gdb 配置信息。与 info 不同, show 查看 GDB 本身的配置信息 |
set | 设置变量值。有时指定变量类型才能设置,如 set *(int*)(&a) = 3 |
whatis | 查看变量、函数类型。例如,whatis a 可以显示变量 a 的类型 |
ptype | 查看变量、函数类型。会显示完整的结构体类型 |
print[p] | 打印变量的值。例如,print x 可以显示变量 x 的当前值 |
display | 持续打印变量的值。与 print 类似,但它会在每次停下时自动输出值 |
thread | 切换线程。例如,thread 2 切换到编号为 2 的线程 |
signal | 向进程发送信号。例如,signal 9 发送编号为 9 的信号 |
启动进程,不带参数
# gdb <program>
(gdb) run
启动进程,带参数 <args>
# gdb <program>
(gdb) run <args>
启动 gdb
时传入参数,run
就不用传入了
# gdb --args <program> 1 2 3
(gdb) run
通过 set
设置参数
# gdb <program>
(gdb) set args 1 2 3
(gdb) run
显示运行时将要或已经传递给程序的参数
(gdb) show args
在启动进程前,添加环境变量
(gdb) set env DEBUG 1
在启动进程前,清除环境变量
(gdb) unset env DEBUG
通过进程号 123
连接到正在运行的进程
(gdb) attach 123
默认情况下,linux
系统中程序崩溃时也不会生成 core dump
文件,需要先启用
ulimit -c unlimited
echo "/tmp/core-%e-%p-%t" > /proc/sys/kernel/core_pattern
调试 core
文件
gdb program /tmp/core-file
命令 | 说明 |
---|---|
(gdb) list 30 | 查看第 30 行为中心的上下 5 行源码 |
(gdb) list main | 查看 main 函数为中心的上下 5 行源码 |
(gdb) list file.c:30 | 查看 file.c 文件中 30 行的源码 |
(gdb) list file.c:main | 查看 file.c 文件中 main 函数 |
(gdb) disassemble | 查看当前可执行文件的汇编源码 |
(gdb) disassemble myfun | 查看指定函数的汇编源码 |
命令 | 说明 |
---|---|
(gdb) step[s] | 执行源码级别的单步进入操作 |
(gdb) stepi[si] | 执行指令级别的单步进入操作 |
(gdb) next[n] | 执行源码级别的单步跳过操作 |
(gdb) nexti[ni] | 执行指令级别的单步跳过操作 |
(gdb) continue[c] | 继续执行,到下一个断点或程序结束 |
(gdb) finish | 运行完当前函数,并返回到函数调用点 |
(gdb) return | 直接退出当前函数,不执行剩下代码块 |
(gdb) return expression | 可以指定返回值的内容 |
(gdb) until | 结束当前循环 |
命令 | 说明 |
---|---|
(gdb) break main | 在所有名为 main 的函数处设置一个断点 |
(gdb) break test.c:12 | 在文件 test.c 的第 12 行设置断点 |
(gdb) break test.c:func | 在文件 test.c 的 func 函数处设置断点 |
(gdb) rbreak regular-expression | 在正则表达式匹配的函数名上设置断点 |
(gdb) break foo if a < 100 | 设置条件断点,条件满足才停止 |
(gdb) info break | 列出所有断点位置、编号 |
(gdb) delete 2 | 删除指定编号的断点 |
(gdb) clear | 删除刚才停止处的断点 |
(gdb) disable 1 | disable 指定编号的断点 |
(gdb) enable 1 | enable 指定编号的断点 |
命令 | 说明 |
---|---|
(gdb) watch var | 监视变量,当值变化时会输出新、旧值 |
(gdb) info break | 列出断点,也包括 watchpoint |
(gdb) i watch | 只列出 watchpoint |
(gdb) delete 1 | 删除指定的 watchpoint |
命令 | 说明 |
---|---|
(gdb) info args | 查看传入参数信息 |
(gdb) info local | 查看当前栈帧(函数)的本地变量 |
(gdb) print var | 查看指定变量的值 |
(gdb) print/x var | 以十六进制输出变量的值 |
(gdb) print ptr | 假设 int *ptr=&a ,输出变量 a 的地址 |
(gdb) print *ptr | 假设 int *ptr=&a ,输出变量 a 的值 |
(gdb) print *ptr@5 | 假设 int ptr[5] ,输出数组的值 |
(gdb) display var | 与 print 作用相同,但每次停下来都自动输出变量的值 |
(gdb) info display | 列出所有设置了 display 的变量 |
(gdb) undisplay 1 | 与 display 相反,不能指定变量名,只能是编号 |
(gdb) delete display 1 | 与 undisplay 类似,通过编号取消显示 |
(gdb) whatis var | 查看变量类型 |
(gdb) ptype var | 比 type 更详细,会给出结构体的定义 |
每当一个函数被调用时,一个新的栈帧 frame
就会被压入栈中,栈帧包含了该函数的局部变量、参数、返回地址和其他信息,当函数执行完毕后,这个栈帧会被弹出栈并销毁。
命令 | 说明 |
---|---|
(gdb) frame | 显示当前栈帧和源代码行 |
(gdb) backtrace | 打印出当前正在执行的所有栈帧 |
(gdb) backtrace 5 | 只显示最近调用的 5 个栈帧 |
(gdb) frame 2 | 切换到第 2 个栈帧,以查看信息 |
(gdb) up | 切换到上一级调用栈帧 |
(gdb) down | 切换到下一级调用栈帧 |
call
和 print
调用的函数如果存在全局变量、静态变量的修改,在函数返回后会恢复到调用之前的值,这两个调用不会影响程序的状态
命令 | 说明 |
---|---|
(gdb) call func(a, b) | 调用指定的函数,不影响主线程变量 |
(gdb) print func(a, b) | 与 call 类似 |
(gdb) finish | 结束当前运行的函数 |
linux
下使用 kill -l
查看信号编号与信号名,使用 info signal
查看信号的处理方式、描述等:
(gdb) info signal
Signal Stop Print Pass to program Description
SIGHUP Yes Yes Yes Hangup
SIGINT Yes Yes No Interrupt
SIGQUIT Yes Yes Yes Quit
SIGILL Yes Yes Yes Illegal instruction
命令 | 说明 |
---|---|
(gdb) signal SIGKILL | 向进程发送信号,用信号名或编号表示 |
(gdb) signal 9 | 向进程发送信号,用信号名或编号表示 |
(gdb) handle <signal> actions | 指定信号的处理方式,选择如下,可以组合 |
stop/nostop | 收到信号是否停止进程,类似断点 |
print/noprint | 收到信号是否输出消息 |
pass/nopass | 是否将信号传递给程序 |
命令 | 说明 |
---|---|
(gdb) info threads | 列出所有线程,标识当前所在线程 |
(gdb) thread 2 | 切换到编号为 2 的线程 |
(gdb) break file.c:23 thread all | 在所有线程中相应的行上设置断点 |
(gdb) thread apply all command | 让所有线程执行 gdb 命令 |
(gdb) thread apply ID1 ID2 command | 让指定线程执行 gdb 命令 |
(gdb) set scheduler-locking off | 所有线程都执行,这是默认值 |
(gdb) set scheduler-locking on | 只让当前线程执行 |