启用GDB调试
想要使用GDB调试应用,首先在编译的时候就要指定使用GDB调试,否则虽然可以调试,但没法在调试窗口直接查看源码、符号、详细的调用栈等,所以,编译是调试的第一步
gcc xx.c -o ngdb #这是不带有调试信息的
gcc -g xx.c -o ygdb #加上-g,带调试,且需避免使用编译优化
使用gdb命令运行可执行文件
gdb ./ygdb
此时会进入gdb调试窗口,如果想退出调试,按下q
断点
断点分类
| 断点类型 | 定义 | 命令格式 | 示例 | 应用场景 |
|---|
| 行断点 | 在源代码特定行设置断点,程序执行到该行时中断 | b 文件名:行号 | b main.c:20 | 调试特定代码行的逻辑错误,如循环中的变量变化 |
| 函数断点 | 在函数入口处设置断点,调用该函数时触发 | b 函数名 | b calculate_sum | 快速定位函数调用入口,分析函数参数或内部逻辑 |
| 条件断点 | 仅当满足预设条件时触发断点 | b 行号 if 条件 | b 20 if x > 100 | 精准控制断点触发逻辑,避免无效中断(如循环中特定迭代) |
| 硬件断点 | 利用CPU硬件特性监控内存/寄存器访问 | hbreak 地址 | hbreak *0x4005a0 | 高效监控内存读写或执行,适用于底层调试或性能敏感场景 |
| 临时断点 | 触发一次后自动删除,减少断点管理负担 | tbreak 行号 | tbreak main | 一次性调试场景,如初始化代码或单次异常捕获 |
| 捕捉断点 | 捕获程序运行中的特定事件(如异常、信号) | catch 事件类型 | catch throw(捕获C++异常) | 事件驱动调试,如异常处理、库加载/卸载、系统调用 |
| 观察断点 | 监控变量值变化(读/写/修改)时触发 | watch 变量 | watch x | 追踪数据被意外修改的场景,如数组越界、全局变量篡改 |
| 地址断点 | 在特定内存地址设置断点,常用于汇编级调试 | b *地址 | b *0x4005a0 | 底层调试,如分析指令执行流程、内存地址访问 |
| 线程断点 | 仅在指定线程执行到断点时触发 | b 行号 thread 线程ID | b 20 thread 1 | 多线程调试,精准定位线程特定行为(如竞态条件) |
| 共享库断点 | 共享库加载/卸载时触发断点 | break load 库名 | break load libexample.so | 动态链接调试,监控库函数调用或插件加载过程 |
| 静态断点 | 程序启动前设置断点,确保断点在运行初期生效 | break 文件名:行号(未运行时) | break main.c:10 | 初始化代码调试,如全局变量初始化、构造函数调用 |
| 动态断点 | 程序运行时动态设置断点,支持即时调整 | break 行号(运行时执行) | 运行时输入b 30 | 即时调试场景,如根据运行时状态动态调整断点位置 |
断点操作
设置
| 命令全称 | 缩写 | 用法说明 | 示例 |
|---|
break | b | 在指定位置设置断点 | b main.c:20(在main.c第20行设断点) |
hbreak | hb | 设置硬件断点(需硬件支持) | hb *0x4005a0(在地址0x4005a0设硬件断点) |
tbreak | tb | 设置临时断点(触发后自动删除) | tb main(在main函数入口设临时断点) |
catch | c | 捕获特定事件(如异常、信号) | catch throw(捕获C++异常抛出) |
watch | w | 设置观察断点(监控变量变化) | watch x(监控变量x的变化) |
rwatch | | 被读观察点 | rwatch x |
awatch | | 读写观察点 | awatch x |
管理断点
| 命令全称 | 缩写 | 用法说明 | 示例 |
|---|
enable | en | 启用断点 | enable 1(启用编号为1的断点) |
disable | dis | 禁用断点(保留但暂不触发) | disable 2(禁用编号为2的断点) |
delete | d | 删除断点 | d 3(删除编号为3的断点) |
clear | cl | 删除指定位置的断点 | cl main.c:25(删除main.c第25行的断点) |
修改断点属性
| 命令全称 | 缩写 | 用法说明 | 示例 |
|---|
condition | cond | 设置/修改断点条件 | cond 1 x>10(设置断点1的条件为x>10) |
ignore | ig | 设置断点忽略次数 | ig 1 5(忽略断点1的前5次触发) |
commands | comm | 设置断点触发时的命令序列 | comm 1(设置断点1触发时的自定义命令) |
silicon | si | 修改断点的硬件属性(如读写监控) | si 1 r(设置断点1监控读取操作) |
查看断点
| 命令全称 | 缩写 | 用法说明 | 示例 |
|---|
info break | i b | 查看所有断点信息 | i b(显示所有断点的编号、状态、位置等) |
info watch | i w | 查看观察断点信息 | i w(显示所有观察断点的监控变量及状态) |
info catch | i c | 查看捕捉断点信息 | i c(显示所有捕捉断点的事件类型及状态) |
运行控制
文件与基本控制
| 命令全称 | 缩写 | 用法说明 | 示例 |
|---|
file | f | 加载要调试的可执行文件。GDB 需要知道文件名才能设置断点等。 | file /path/to/my_program |
run | r | 启动被调试的程序。可以跟命令行参数。 | run arg1 arg2 |
kill | k | 终止正在调试的程序。 | kill |
quit | q | 退出 GDB。 | quit |
set args | - | 设置程序下次 run 时使用的命令行参数。 | set args -f -o output.txt |
show args | - | 显示当前设置的命令行参数。 | show args |
attach | - | 附加到一个正在运行的进程上进行调试。需要进程ID (PID)。 | attach 12345 |
detach | - | 从附加的进程上分离,让其继续独立运行。 | detach |
exec-file | - | 加载一个新的可执行文件,用于调试核心转储 (core dump)。 | exec-file my_program |
core-file | c | 加载一个核心转储文件,用于分析程序崩溃时的状态。 | core-file core.12345 |
程序运行控制
| 命令全称 | 缩写 | 用法说明 | 示例 |
|---|
start | | 启动程序并停在main函数入口 | start |
kill | k | 终止正在运行的程序 | kill |
run | r | 启动程序并运行,直到遇到断点或程序结束 | run 或 r(无参数时启动程序) |
next | n | 单步执行,跳过函数调用(执行下一行,不进入函数内部) | next 或 n(执行当前行后停在下一行) |
nexti | | 执行一条机器指令,不进入函数调用 | |
step | s | 单步执行,进入函数内部(执行下一行,若为函数调用则进入该函数) | step 或 s(进入函数内部逐行调试) |
stepi | | 执行一条机器级别的指令 | |
continue | c | 继续运行程序,直到遇到下一个断点或程序结束 | continue 或 c(从当前中断点继续运行) |
until | u | 运行程序直到到达指定行,或跳出当前循环/复杂语句 | until 30(运行至第30行)或 until(跳出循环) |
finish | fin | 执行完当前函数的剩余部分并返回,显示函数返回值 | finish 或 fin(结束当前函数调试并返回调用点) |
jump | j | 跳转到指定行或地址执行(可能跳过代码或进入无效路径) | jump 50(跳转到第50行)或 jump *0x4005a0(跳转到地址0x4005a0) |
detach | dt | 分离调试器,让程序继续运行 | detach |
interrupt | i | 中断正在运行的程序(类似Ctrl+C) | interrupt |
return | ret | 从当前函数返回,可指定返回值 | return 5(返回值为5) |
call | ca | 调用函数(可带参数) | call printf("Hello") |
signal | sig | 向程序发送信号 | signal 2(发送SIGINT) |
handle | han | 设置信号处理方式 | handle SIGSEGV nostop(不停在SIGSEGV) |
thread | th | 切换调试线程 | thread 2(切换至线程2) |
frame | f | 切换栈帧 | frame 1(切换至栈帧1) |
up | u | 向栈帧上层移动 | up |
down | d | 向栈帧下层移动 | down |
backtrace | bt | 查看调用栈 | bt |
set | | 修改变量的值。 | set my_var = 100 |
set follow-fork-mode | sfm | 设置子进程调试模式 | set follow-fork-mode child(跟踪子进程) |
set stop-on-solib-events | ssse | 设置是否在共享库事件时停止 | set stop-on-solib-events 1(停止) |
set pagination | sp | 设置是否分页显示输出 | set pagination 0(关闭分页) |
set args | sa | 设置程序启动参数 | set args arg1 arg2 |
set environment | sen | 设置环境变量 | set environment VAR=value |
set scheduler-locking | ssl | 设置线程调度锁定模式 | set scheduler-locking on(锁定调度) |
set step-mode | ssm | 设置单步执行模式(如是否进入函数) | set step-mode on(进入函数) |
set $pc | spc | 修改程序计数器(指令指针) | set $pc = 0x4005a0 |
set $sp | ssp | 修改栈指针 | set $sp = 0x7fffffff0000 |
set $fp | sfp | 修改帧指针 | set $fp = 0x7fffffff0010 |
set $ps | sps | 修改处理器状态 | set $ps = 0x2000(设置特定标志位) |
set $ac | sac | 修改累加器 | set $ac = 0x1234 |
调用栈查看
| 命令全称 | 缩写 | 用法说明 | 示例 |
|---|
backtrace | bt | 显示当前的函数调用栈(回溯)。 | backtrace |
frame | f | 切换到指定的栈帧。frame 0 是当前帧,frame 1 是调用当前函数的帧。 | frame 1 |
info frame | info f | 显示当前栈帧的详细信息,包括参数、局部变量和返回地址。 | info frame |
up | - | 向上移动一个栈帧(向 main 函数方向)。 | up |
down | - | 向下移动一个栈帧(远离 main 函数方向)。 | down |
info args | - | 显示当前栈帧的函数参数。 | info args |
info locals | - | 显示当前栈帧的局部变量。 | info locals |
线程调试
| 命令全称 | 缩写 | 用法说明 | 示例 |
|---|
info threads | info t | 显示所有线程的摘要信息。 | info threads |
thread | t | 切换当前调试的线程。GDB 会显示当前线程号。 | thread 2 |
break ... thread <id> | - | 在指定线程中设置断点。 | b 40 thread 3 |
info inferiors | - | 显示所有被调试的进程(通常用于调试子进程)。 | info inferiors |
inferior | - | 切换当前调试的进程。 | inferior 2 |
源代码查看
| 命令全称 | 缩写 | 用法说明 | 示例 |
|---|
list | l | 显示源代码。默认显示当前行附近的代码。 | list |
list <function> | - | 显示指定函数的源代码。 | list main |
list <line_num> | - | 显示指定行号附近的源代码。 | list 50 |
list <start>, <end> | - | 显示指定行号范围的源代码。 | list 20, 30 |
search | - | 在源代码中搜索正则表达式。 | search my_function |
info source | - | 显示当前正在查看的源文件信息。 | info source |
forward-search | - | 向后搜索。 | forward-search "pattern" |
reverse-search | - | 向前搜索。 | reverse-search "pattern" |
数据查看
| 命令全称 | 缩写 | 用法说明 | 示例 |
|---|
| x | | 内存检查(十六进制/ASCII格式) | x/4xw &data(检查data地址开始的4个字) |
| print | p | 打印变量或表达式的值。 | p my_var
p *ptr
p obj.member |
| ptype | pt | 查看变量/类型的定义 | ptype int(查看int类型定义)或 ptype struct mystruct |
| whatis | w | 查看表达式类型 | whatis data(显示data的类型) |
| disassemble | disas | 反汇编当前函数或指定地址 | disassemble main(反汇编main函数)或 disas 0x4005a0 |
| inspect | ins | 检查对象内存布局 | inspect obj(显示对象obj的内存结构) |
| display | | 设置一个表达式,每次程序暂停时自动显示其值。 | display my_counter |
| undisplay | | 停止自动显示某个表达式 | undisplay 1 |
| info display | | 显示所有设置了自动显示的表达式。 | info display |
| info registers | i r | 查看所有寄存器状态 | info registers(显示通用寄存器值) |
| info threads | i th | 查看线程列表及状态 | info threads(显示所有线程ID及当前执行位置) |
| info stack | i s | 查看调用栈(同backtrace) | info stack 或 bt(显示完整调用栈) |
| info frame | i f | 查看当前栈帧详细信息 | info frame(显示栈帧基址、返回地址等) |
| info functions | | 显示所有函数名(可配合 regex)。 | info functions ^main |
| info variables | | 显示所有全局/静态变量名。 | info variables |
| info locals | i l | 查看当前栈帧的局部变量 | info locals(列出所有局部变量及值) |
| info args | i a | 查看当前函数的参数 | info args(显示函数参数名及值) |
| info addr | i ad | 查看符号的地址 | info addr data(显示变量data的内存地址) |
| info line | i li | 查看源代码行信息 | info line 20(显示第20行的地址范围及代码) |
| info files | i f | 查看目标文件信息 | info files(显示可执行文件、符号文件路径) |
| info target | i t | 查看当前调试目标信息 | info target(显示目标文件、架构、符号加载状态) |
| info sharedlibrary | i sh | 查看共享库加载信息 | info sharedlibrary(显示已加载的共享库及地址范围) |
| info proc | i p | 查看进程信息(内存映射、寄存器等) | info proc mappings(显示进程内存映射区域) |
| info signals | i sig | 查看信号处理设置 | info signals(显示信号与处理函数的映射关系) |
| info types | i ty | 查看已定义的类型 | info types(列出所有已定义的结构体、联合体等) |
| info symbol | i sy | 查看地址对应的符号 | info symbol 0x4005a0(显示该地址对应的函数/变量名) |
| info address | i ad | 查看地址对应的符号及段信息 | info address 0x7fffffff0000(显示地址所在的段及符号) |
| info catch | i c | 查看捕捉断点信息 | info catch(显示已设置的异常/事件捕捉断点) |
| info watch | i w | 查看观察断点信息 | info watch(显示所有变量监控断点及状态) |
| info break | i b | 查看断点信息(同info breakpoints) | info break(显示所有断点编号、位置、状态) |
| show | | 查看GDB设置参数(与set对应) | show pagination(查看是否启用分页模式) |
| help | h | 查看命令帮助文档 | help break(显示break命令的详细用法) |
GDB环境与设置
| 命令全称 | 缩写 | 用法说明 | 示例 |
|---|
set | - | 设置 GDB 的各种内部变量。 | set print pretty on |
show | - | 显示 GDB 的内部变量设置。 | show print pretty |
set logging on | - | 开启日志记录,将 GDB 的输出保存到文件。 | set logging on |
set logging off | - | 关闭日志记录。 | set logging off |
set prompt | - | 自定义 GDB 的命令提示符。 | set prompt (gdb) |
set height | - | 设置命令的显示高度,0 表示无限制。 | set height 0 |
set width | - | 设置命令的显示宽度。 | set width 120 |
source | - | 从文件中读取并执行 GDB 命令。 | source ~/.gdbinit |
help | h | 显示帮助信息。help 显示所有命令分类,help <command> 显示具体命令的帮助。 | help
help run |
非停止模式(Non-Stop Mode)
这是一个高级功能,允许在调试多线程程序时,即使一个线程命中断点,其他线程也可以继续运行。
| 命令全称 | 缩写 | 用法说明 | 示例 |
|---|
set non-stop on | - | 开启非停止模式。 | set non-stop on |
set non-stop off | - | 关闭非停止模式(默认)。 | set non-stop off |
continue& | c& | 在非停止模式下,让所有线程继续执行。 | continue& |
next& | n& | 在非停止模式下,让当前线程执行下一行。 | next& |
step& | s& | 在非停止模式下,让当前线程步入下一行。 | step& |
interrupt | - | 在非停止模式下,中断所有线程的执行。 | interrupt |