目录
一、基本概念与准备
GDB(GNU Debugger)是Linux环境下功能强大的调试工具,能够帮助开发者快速定位和解决程序中的问题。在使用GDB之前,我们需要确保程序编译时包含调试信息:
gcc -g program.c -o program
这个-g
选项会在可执行文件中嵌入调试符号,使得GDB能够将机器指令与源代码对应起来。需要注意的是,调试信息会增加可执行文件的大小,但不会影响程序的执行逻辑。
二、启动GDB
GDB提供了多种启动方式,适用于不同的调试场景:
- 调试可执行文件:
gdb ./program
- 调试正在运行的进程:
gdb program PID
- 分析核心转储文件:
gdb program core
在Linux系统中,默认配置下不会生成core文件。如果需要分析程序崩溃时的状态,可以通过以下命令启用core文件生成:
ulimit -c unlimited
三、基本调试命令 📋
程序运行控制
run
(简写r
):启动程序执行continue
(简写c
):继续执行直到遇到下一个断点next
(简写n
):单步执行,遇到函数调用时不进入函数内部step
(简写s
):单步执行,遇到函数调用时会进入函数内部finish
:执行完当前函数后暂停
断点管理
break
(简写b
):设置断点b 行号
:在指定源代码行设置断点b 函数名
:在函数入口处设置断点
info breakpoints
:查看所有断点信息delete
(简写d
):删除断点d 断点编号
:删除指定断点d
:删除所有断点
四、变量查看与修改 🔍
在调试过程中,查看和修改变量值是常见需求:
print
(简写p
):打印变量值p 变量名
:显示变量当前值p/x 变量名
:以十六进制格式显示
display
:设置自动显示的变量display 变量名
:每次暂停时自动显示该变量
set var
:修改变量值set var 变量名=值
:修改变量的值
五、高级调试技巧 🚀
条件断点
在某些情况下,我们可能希望断点只在特定条件下触发:
break 20 if i == 100
这会在第20行设置一个条件断点,只有当变量i等于100时才会触发。
观察点
观察点用于监控变量的变化:
watch
:设置观察点watch 变量名
:当变量值改变时暂停执行
rwatch
:设置读观察点rwatch 变量名
:当变量被读取时暂停执行
awatch
:设置读写观察点awatch 变量名
:当变量被读取或修改时暂停执行
多线程调试
对于多线程程序,GDB提供了专门的调试命令:
info threads
:显示所有线程信息thread 线程号
:切换到指定线程break 行号 thread 线程号
:在指定线程的某行设置断点
六、调试崩溃程序 💥
当程序崩溃时,GDB可以帮助我们分析原因:
- 首先确保系统允许生成core文件:
ulimit -c unlimited
- 程序崩溃后,使用GDB分析core文件:
gdb program core
- 查看崩溃时的调用栈:
backtrace(简写bt)
- 检查崩溃点的变量状态:
frame 帧号
info locals
七、实用建议 ✨
-
建议在调试时使用
-O0
选项编译程序,避免优化带来的调试困难。 -
可以将常用调试命令写入
.gdbinit
文件,GDB启动时会自动执行这些命令。 -
对于复杂调试场景,可以考虑使用GDB的TUI模式:
gdb -tui program
如果觉得GDB的界面不够友好,可以尝试CGDB,它提供了分屏显示代码的功能。
通过掌握这些GDB调试技巧,开发者可以更高效地定位和解决程序中的问题。调试是一个需要耐心和经验的过程,熟练使用GDB将大大提升调试效率。