用 catch throw、catch syscall brk 或 handle SIGSEGV stop print 捕获崩溃第一现场;编译加 -g -O0 避免内联干扰;对模板函数打具体实例断点;变量显示为 时启用 -fvar-tracking-assignments 或 volatile;启用 libstdc++ pretty-printer 查看 STL 内容。

gdb 启动时程序就崩溃,怎么定位第一现场?
直接用 gdb ./a.out 启动后别急着 run,先设一个“崩溃捕获点”:catch throw(C++ 异常)、catch syscall brk(内存分配失败)、或者更通用的 handle SIGSEGV stop print。这样程序一触发段错误,gdb 就立刻停住,bt 看栈、info registers 看寄存器、x/10i $rip 看出问题的汇编指令——比等 run 完再看 core dump 快得多。
断点打在内联函数或模板实例上没反应?
gcc 编译时默认开启优化(-O2)会把简单函数内联掉,gdb 就找不到原始符号。必须加 -g -O0 重新编译;如果非得带优化调试,至少用 -g -O1 并配合 set debug inline-debug 1 查看内联展开信息。另外模板函数要打具体实例的断点,比如 std::vector,而不是 std::vector::push_back —— 后者 gdb 根本不认。
变量显示为 怎么办?
这是最常见也最烦人的提示,本质是编译器把变量存在寄存器里、没写回栈,或者被整个优化掉了。解决路径很明确:
- 编译加
-O0 -g(开发阶段首选) - 若必须开优化,加
-O2 -g -fvar-tracking-assignments(GCC ≥4.7),让调试信息更精细 - 用
print &var_name看地址,再x/d &var_name手动读内存(适用于局部变量未被完全消除的情况) - 临时加
volatile声明(仅调试用):volatile int x = 42;,阻止编译器优化该变量
想看 STL 容器内容却只能看到指针和 size?
gdb 默认对 std::vector、std::string 等只显示结构体字段,看不到实际数据。启用 Python 脚本支持就能自动展开:
立即学习“C++免费学习笔记(深入)”;
- 确认 gdb 支持 Python:
gdb --version输出含python - 加载 GCC 自带的 pretty-printer:
source /usr/share/gcc-*/python/libstdcxx/v6/printers.py(路径按实际 GCC 版本调整) - 之后
print vec就能直接看到 vector 内容,print str显示 string 字符串而非指针 - 如遇路径问题,可改用
set auto-load safe-path /允许自动加载,再运行程序触发 auto-load
没有 pretty-printer 时,硬查 std::vector 得靠 print *(int*)vec._M_impl._M_start@vec.size() 这类表达式,既难写又易错——别硬扛,配好脚本是底线。











