本文约2000字,在Linux环境开发C/C++程序,难免遇到崩溃、逻辑异常、内存泄漏等问题,肉眼排查往往事半功倍。
GDB(GNU Debugger)作为GNU项目开发的命令行调试工具,能精准定位问题、监控程序执行、查看内存变量,是Linux后端、嵌入式开发的必备技能。
本文从准备工作到核心命令、实战案例,新手也能快速上手,收藏备用。
我建了一个BSP学习交流群,想学BSP或者已经是BSP开发者可私信我,加入群,一起交流学习,共同进步。
关注公众号, 即可获得与Linux相关的电子书籍以及常用开发工具,文末有文档清单。
GDB调试的前提的是程序包含调试信息,且系统已安装GDB工具,两步搞定准备工作。
# Ubuntu/Debian 系列sudo apt update && sudo apt install gdb -y# CentOS/RHEL 系列sudo yum install gdb -y# 验证安装gdb --version编译时必须加 \-g 选项(生成调试信息),建议关闭优化(\-O0),避免代码执行流程与源代码不一致。
# C程序编译(示例:test.c)gcc -g -O0 test.c -o test# C++程序编译(示例:test.cpp)g++ -g -O0 test.cpp -o test# 验证调试信息(输出含"with debug info"即成功)file test# 1. 直接调试可执行文件(最常用)gdb ./test# 2. 调试正在运行的进程(需PID)gdb -p 12345 # PID通过 ps -ef | grep test 查看# 3. 调试崩溃生成的核心转储文件gdb ./test core.12345# 4. 带命令行参数启动gdb --args ./test arg1 arg2启动后进入\(gdb\) 命令行模式,即可开始调试。
GDB命令支持简写,以下整理高频核心命令,按使用场景分类,附简单示例,好记好用。
\(gdb\) r | |||
\(gdb\) c | |||
\(gdb\) n | |||
\(gdb\) s | |||
\(gdb\) finish | |||
\(gdb\) q |
b 10b sum | |||
tb 12 | |||
b sum if a==10 | |||
\(gdb\) info b | |||
d 1 |
适合排查“变量被意外修改”“内存越界”,依赖硬件支持,常用3种:
watch res | ||
rwatch x | ||
awatch result |
p xp /x x(十六进制) | |||
disp res | |||
\(gdb\) info locals | |||
x/10xw \&x | |||
set x=30 |
程序崩溃时,通过堆栈回溯快速定位问题,核心命令2个:
\(gdb\) bt | |||
f 1(切换到上一层) |
结合简单示例,演示完整调试流程,快速掌握命令用法。
程序意图计算1~n的和,循环条件错误导致结果异常(少加最后一个数):
# test_sum.c#include<stdio.h>intcal_sum(int n){int sum = 0;for (int i = 1; i < n; i++) { // 错误:应为i <= n sum += i; }return sum;}intmain(){int n = 10;int result = cal_sum(n);printf("1~%d 的和为:%d\n", n, result);return0;}# 1. 编译带调试信息gcc -g -O0 test_sum.c -o test_sum# 2. 启动GDB,设断点gdb ./test_sum(gdb) b cal_sum # 函数入口设断点(gdb) b 6 # 循环内设断点# 3. 启动程序,单步执行(gdb) r # 停在cal_sum入口(gdb) n # 单步执行,进入循环(gdb) p sum # 查看sum值(初始0)(gdb) p i # 查看i值(初始1)# 4. 观察循环,定位错误(gdb) c # 继续执行,直到循环结束(gdb) p i # 循环结束时i=10,未进入循环执行sum +=10(gdb) p sum # sum=45,少加10,定位到循环条件错误# 5. 验证修改(无需重新编译)(gdb) set i=10(gdb) set sum=sum+i # sum=55(gdb) c # 继续执行,输出正确结果# 6. 退出GDB(gdb) q多线程调试:info threads 查看线程,thread 3 切换线程,thread apply all bt 查看所有线程堆栈。
远程调试:目标机 gdbserver 192\.168\.1\.100:1234 \./test,本地 target remote 192\.168\.1\.100:1234 连接。
美化打印:set print pretty on 美化结构体、STL容器显示。
忘记加 \-g 编译,导致无法关联源代码。
开启编译器优化(\-O1/\-O2),导致调试时行号错乱、变量无法查看,调试用 \-O0。
多线程调试未锁定调度器(set scheduler\-locking on),线程切换干扰调试。
GDB调试核心是“控制执行、设置断点、查看数据、回溯堆栈”,掌握本文核心命令,就能应对绝大多数C/C++程序调试场景。
新手先熟练 break、run、next、print、bt 这5个命令,多实践就能灵活运用,快速解决程序bug

这里是女程序员的笔记本
15年+嵌入式软件工程师兼二胎宝妈
分享读书心得、工作经验,自我成长和生活方式。
希望我的文字能对你有所帮助