返回首页

GDB 调试 C++:几分钟内找到段错误

针对 C++ 开发者的 GDB 指南,专注于找到段错误、设置断点、查看变量和 TUI 模式。基于真实崩溃示例和无需重新编译的代码导航。

C++ 中的 GDB:从段错误到快速调试
Advertisement 728x90

GDB:无惧段错误的逐行C++调试指南

GDB能在15到30秒内精准定位程序崩溃位置。与其反复添加打印语句并重新编译,不如使用调试器实时查看调用栈和变量值。编译时务必加上 -g -O0 以保留调试信息:

g++ -g -O0 -o myprogram myprogram.cpp

通过 file myprogram 确认调试信息已包含。启动调试:gdb ./myprogram,然后输入 run。发生段错误时,GDB会自动暂停,并通过 backtrace(bt)显示确切位置。

std::string::operator= 中因 this 指针为空导致崩溃,会在调用栈中立即显现:

Google AdInline article slot
#0 0x... in std::string::operator= (this=0x0, ...)
#1 0x... in UserData::setName (...)
#2 0x... in main ()

启用可读输出:set print pretty onset print demangle on

断点与代码单步执行

设置断点以控制程序运行:

  • break main —— 在 main 函数入口处设断点
  • break program.cpp:42 —— 在特定行设断点
  • break UserData::setName —— 进入某个方法时触发
  • info break —— 查看所有断点列表

对于重载的C++函数,需指定参数签名:break print(int)break print(std::string)。高级用法:rbreak ^.*::print$ 可通过正则匹配所有名为 print 的方法。

Google AdInline article slot

代码导航命令如下:

| 命令 | 快捷键 | 动作 |

|------|--------|------|

Google AdInline article slot

| next | n | 执行下一行,不进入函数内部 |

| step | s | 执行下一行,并进入函数内部 |

| finish | fin | 继续运行至当前函数结束 |

| continue | c | 继续运行直到下一个断点 |

在C++中,避免对STL函数如 push_back 使用 step —— 应使用 next 跳过库内部实现。

检查变量与对象状态

以下命令用于查看数据内容:

  • print variable_name —— 查看变量值
  • print *pointer —— 解引用指针
  • print vec.size() —— 调用成员方法
  • display variable_name —— 每次单步后自动显示变量
  • info locals —— 显示局部变量
  • info args —— 显示函数参数

GDB能正确解析C++类型:

print myVector
$1 = std::vector of length 5, capacity 8 = {1, 2, 3, 4, 5}

print myString
$2 = "Hello, World!"

若看到 <optimized out>,说明优化级别过高,请用 -O0 重新编译。若未加 -g,变量名将无法显示。

TUI模式:可视化调试利器

启用 tui enable 后,屏幕分为上下两部分:上方显示源码并高亮当前行,下方展示命令行。常用操作:

  • layout src —— 源码视图
  • layout asm —— 汇编视图
  • layout split —— 源码+汇编并列
  • layout regs —— 寄存器窗口
  • Ctrl + X, 2 —— 分为两个窗口
  • Ctrl + X, o —— 切换窗口焦点
  • Ctrl + X, a —— 退出TUI模式

TUI模式通过上下文可视性,大幅降低复杂项目中的理解负担,无需依赖行号。

常见问题与解决方案

| 问题 | 解决方案 |

|------|----------|

| <optimized out> | 用 -O0 重新编译 |

| 无变量名显示 | 添加 -g 标志 |

| 局部变量缺失 | 在函数内运行 info locals |

| vector显示乱码 | 在旧版 libstdc++ 中使用 print vec._M_impl._M_start |

中级开发者必备的10个核心命令

掌握这10条命令,可应对90%的调试场景:

  • r —— 运行程序
  • b —— 设置断点
  • bt —— 查看调用栈
  • n —— 下一步(不进函数)
  • s —— 单步进入函数
  • fin —— 执行完当前函数
  • c —— 继续运行
  • p —— 打印变量值
  • i locals —— 查看局部变量
  • q —— 退出GDB

关键要点

  • 调用栈(bt 可在数秒内解决70%的段错误,清晰还原从崩溃点回溯至 main 的完整路径。
  • TUI模式 提供直观的代码视图,显著降低复杂项目中的认知压力。
  • -g -O0 是必须项;缺少它们,调试几乎毫无意义。
  • nextstep 的选择 在使用STL时至关重要——避免陷入库函数内部。
  • displayinfo locals/args 让你全面掌握程序状态,无需在代码中插入大量打印语句。

— Editorial Team

Advertisement 728x90

继续阅读