常用命令
[] 内为命令缩写
命令 [缩写]说明help[h]查看命令帮助。如 help runrun[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) = 3whatis查看变量、函数类型。例如,whatis a 可以显示变量 a 的类型ptype查看变量、函数类型。会显示完整的结构体类型print[p]打印变量的值。例如,print x 可以显示变量 x 的当前值display持续打印变量的值。与 print 类似,但它会在每次停下时自动输出值thread切换线程。例如,thread 2 切换到编号为 2 的线程signal向进程发送信号。例如,signal 9 发送编号为 9 的信号
启动调试
启动进程,不带参数
# gdb
(gdb) run
启动进程,带参数
# gdb
(gdb) run
启动 gdb 时传入参数,run 就不用传入了
# gdb --args
(gdb) run
通过 set 设置参数
# gdb
(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 1disable 指定编号的断点(gdb) enable 1enable 指定编号的断点
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
线程
命令说明(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只让当前线程执行