GDB 速查表
GDB速查表提供了对 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
core dump 文件
默认情况下,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指定编号的断点 | 
watch 命令
| 命令 | 说明 | 
|---|---|
| (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 栈帧
每当一个函数被调用时,一个新的栈帧 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 | 只让当前线程执行 | 
另见
                声明 定期同步开源项目
    reference
            
        评论
欢迎提交文档错误或者建议。提交成功后自己可见,其他用户待审核通过后才可见。
            您暂未登录
            
    
                必须登录后才能使用评论功能(评论、点赞、回复、删除等),请
    点击跳转登录
。首次评论仅自己可见,待管理员审核通过后,才会对外发布。