Lunix下C/C++调试利器:GDB 完整实操指南(搭配Git开发工作流)

📅 2026/8/4 1:27:59
Lunix下C/C++调试利器:GDB 完整实操指南(搭配Git开发工作流)
前言很多开发人员只懂得printf打印调试效率低下掌握GDB是 C/C 底层开发必备能力。 Git 负责代码版本管控GDB 负责程序运行时故障定位二者构成 Linux 后端、嵌入式开发标准组合。 本文结合流程图从零梳理 GDB 原理、编译参数、常用指令、调试技巧、常见场景。一、前置基础编译必须携带调试符号GDB 无法解析无调试信息的程序。编译参数-ggcc main.c -o main -g # g g main.cpp -o main -g-g向 ELF 可执行文件嵌入源码、行号、变量符号信息拓展-ggdb生成适配 GDB 的专用调试信息 ⚠️ 注意生产环境不要保留-g会增大程序体积、泄露源码信息发布版本编译移除-g。补充strip ./main可以清除程序内调试符号去除调试能力。二、启动 GDB 的几种方式方式 1直接启动程序gdb ./main进入 gdb 交互终端后输入run启动程序。方式 2附加到正在运行的进程attach适合调试后台运行、服务进程# 先找到进程PID ps aux | grep ./main # 附加进程 gdb -p 进程PIDattach 后程序会暂停detach脱离进程程序继续运行。方式 3调试 core 崩溃转储文件程序崩溃产生 core 文件事后离线复盘崩溃现场gdb ./main core.12345开启 core 生成临时生效ulimit -c unlimited三、核心基础指令高频必背进入gdb交互界面后执行指令作用run [参数]启动程序可以传入命令行参数run arg1 arg2start启动程序在 main 函数第一行自动断点停下break 行号/b 行号设置断点b 26break 函数名在函数入口断点b main、b test_funccontinue/c继续运行直到下一个断点next/n单步跳过执行下一行不进入函数内部step/s单步进入遇到函数会跳进函数内部finish运行到当前函数结束返回调用处print 变量/p var打印变量值p a、p ptr-datadisplay 变量持续监视变量每次暂停自动打印list/l查看附近源码l 30查看 30 行周边代码info break查看所有断点delete 断点编号删除断点delete 1quit/q退出 gdb四、进阶调试技巧重点1. 条件断点仅满足条件时程序停下避免频繁中断# 行号28当i100时触发断点 b 28 if i 1002. 观察断点watch监测内存改写监测一块内存内存被修改时自动断住定位野指针、变量异常篡改神器watch num # 变量num发生写入时中断 rwatch num # 变量被读取时中断 awatch num # 读/写都中断3. 栈回溯崩溃定位核心bt程序崩溃、死锁、段错误时最重要命令bt # 简易栈回溯 bt full # 完整栈帧打印所有局部变量输出从上到下当前函数 → 上层调用者直接找到函数调用链路。# 切换栈帧查看上下文 frame 24. 指针、数组、内存查看p *ptr # 打印指针指向内容 p arr[0]10 # 打印数组前10个元素 x/20x ptr # x命令原始内存查看16进制展示20字节内存x/格式 地址内存探查排查缓冲区溢出、非法访问。5. 修改运行时变量动态调试不用改代码、重新编译直接在线修改变量测试分支逻辑set var a 1024五、典型故障场景调试流程场景 1段错误 Segmentation fault编译程序加-ggdb ./main→run等待程序崩溃崩溃自动暂停直接执行bt查看调用栈定位出错代码行场景 2程序死循环、卡死gdb -p 进程PIDattach 目标进程程序暂停bt查看所有调用栈找到循环所在函数list查看对应代码分析循环条件场景 3变量莫名被篡改直接使用watch监视变量等待内存写入触发断点。六、GDB Git 开发协作流程结合原图工作流git 拉取代码修改源码git add / git commit保存版本快照使用gcc -g编译带调试符号程序gdb 调试定位 bug修改代码再次编译调试确认修复完成提交新版本到 git 仓库。规范调试编译带-g正式发布移除-g开启-O2优化⚠️ 注意开启编译器优化-O2后变量可能被优化gdb 调试会出现变量无法查看、代码行跳跃调试阶段建议关闭优化。七、常见坑总结忘记加-g调试参数 → gdb 看不到源码、变量发布程序带调试符号存在安全风险开启高优化等级-O2/-O3调试代码和源码行对不上core 文件无法生成执行ulimit -c unlimitedstep(s)无法进入函数函数没有调试信息静态库未使用 - g 编译多线程程序调试info threads查看线程thread 编号切换线程。拓展多线程调试指令info threads # 列出所有线程 thread 3 # 切换到3号线程 set scheduler-lock on # 锁定调度调试时禁止其他线程运行避免干扰