一、GDB入门:从零开始认识这个调试利器

说实话,我接触GDB已经十几年了。刚入行那会儿,总觉得调试就是printf大法,直到有一次线上崩溃问题折腾了我整整三天——嗯,从那以后我就老老实实学GDB了。

GDB是什么?全称GNU Debugger,是Linux下最经典的调试工具。没有图形界面,全靠命令行。但你别小看它,它比任何IDE调试器都强大。我个人的习惯是:写代码用IDE,调试必开GDB。

GDB能做什么?

说白了,GDB能帮你回答三个问题:

  • 程序在哪儿崩了?——定位段错误、非法指令
  • 变量值是什么?——查看内存、寄存器、堆栈
  • 执行流程怎么走的?——单步跟踪、断点控制

我在项目中遇到过最典型的场景:一个服务跑着跑着就挂了,日志里啥也没有。用GDB attach上去,等它再崩的时候,backtrace一看,哦,野指针。这种问题printf根本查不出来。

核心能力一览:

功能说明常用命令
断点调试在指定行/函数暂停break, watch
单步执行逐行/逐指令运行step, next, stepi
变量查看打印变量、内存、寄存器print, x, info registers
堆栈回溯查看函数调用链backtrace, frame
条件断点满足条件才触发break if

GDB的安装与启动

安装其实很简单。大多数Linux发行版都自带,如果没有:

# Ubuntu/Debian
sudo apt-get install gdb

# CentOS/RHEL
sudo yum install gdb

# 验证安装
gdb --version

启动方式有三种,你想想看哪种适合你:

  1. 直接调试:gdb ./myprogram —— 最常用
  2. 附加进程:gdb -p 12345 —— 调试正在运行的程序
  3. 分析core文件:gdb ./myprogram core.12345 —— 事后分析崩溃

我的小技巧:调试前记得编译时加 -g 选项。不加的话,你看到的全是汇编,那酸爽...我曾经吃过这个亏,编译脚本里忘了加-g,调试了一下午全是问号。

基本命令概览

刚开始学GDB,你不需要记住所有命令。记住这几个就够了:

# 启动与退出
gdb ./a.out        # 启动
quit               # 退出(或Ctrl+D)

# 运行控制
run                # 运行程序
start              # 运行并停在main函数
continue           # 继续执行(简写c)

# 断点操作
break main         # 在main函数设断点(简写b)
break 42           # 在第42行设断点
info breakpoints   # 查看所有断点
delete 1           # 删除编号1的断点

# 单步调试
step               # 进入函数内部(简写s)
next               # 跳过函数(简写n)
finish             # 执行完当前函数

# 查看信息
print var          # 打印变量值(简写p)
backtrace          # 查看调用栈(简写bt)
list               # 查看源代码(简写l)

为什么会这样设计?因为GDB的哲学是:常用命令越短越好。你想想看,调试的时候谁有功夫打完整单词?所以b、c、n、s这些单字母命令,用熟了效率极高。

注意:GDB默认使用AT&T汇编语法。如果你习惯Intel语法,可以在~/.gdbinit里加上 set disassembly-flavor intel。我个人的习惯是用Intel,看着顺眼。

知识体系总览

下面这张图是我自己整理的GDB入门知识结构,你可以照着这个路径学习:

GDB入门 GDB是什么 GNU调试器 命令行工具 无图形界面 能做什么 定位崩溃 查看变量/内存 控制执行流程 安装与启动 apt-get / yum gdb ./program gdb -p / core 基本命令 break / run / continue step / next / finish print / backtrace / list 核心:断点 + 单步 + 查看 = 解决90%的调试问题

这张图把GDB入门拆成了四个模块。我个人建议的学习顺序是:先搞懂GDB能做什么,再装好环境,然后照着基本命令练一遍。别贪多,一天学会run、break、next、print这四个命令,你就已经能解决大部分问题了。

一句话总结:GDB就是程序员的显微镜。printf只能看到你想看的,GDB能看到你没想过的。

好了,这一章就到这里。记住,调试不是写代码的附属品,它是开发的一部分。早点学会GDB,你写代码的底气都会不一样。

可可精品资料库