C++ 调试流程 (GDB)

C++ 调试流程 (GDB)

1. 编译准备

# 使用 -g 选项编译,包含调试信息
g++ -g -o program program.cpp

2. 启动 GDB

gdb ./program           # 调试可执行文件
gdb ./program core      # 调试 core dump 文件
gdb -p <pid>            # 附加到运行中的进程

3. 设置断点

(gdb) break main              # 在 main 函数设置断点
(gdb) break Class::Method     # 在类成员函数设置断点
(gdb) break file.cpp:42       # 在指定文件的行号设置断点
(gdb) break namespace::func   # 在命名空间函数设置断点
(gdb) info breakpoints        # 查看所有断点

4. 运行程序

(gdb) run [args]              # 运行程序(可带参数)
(gdb) start                   # 运行并在 main 处停止

5. 单步执行

(gdb) next (n)                # 单步执行(不进入函数/方法)
(gdb) step (s)                # 单步执行(进入函数/方法)
(gdb) continue (c)            # 继续执行到下一个断点
(gdb) finish                  # 执行到当前函数/方法返回

6. 检查变量和对象

(gdb) print var               # 打印基本变量
(gdb) print object            # 打印整个对象(查看成员)
(gdb) print object.member     # 打印特定成员变量
(gdb) print *ptr              # 打印指针指向的对象
(gdb) print vec[0]            # 访问 STL 容器元素
(gdb) set print object on     # 开启多态类型显示(显示派生类真实类型)
(gdb) set print pretty on     # 格式化输出(结构体/类更易读)

7. 查看调用栈

(gdb) backtrace (bt)          # 显示完整调用栈
(gdb) frame <n>               # 切换到指定栈帧
(gdb) up/down                 # 在栈帧间移动
(gdb) info locals             # 查看当前栈帧的局部变量

8. C++ 特有错误与异常诊断

捕获异常 (Uncaught Exceptions):

(gdb) catch throw             # 在抛出异常时停止
(gdb) catch catch             # 在捕获异常时停止
(gdb) run
# 停止后
(gdb) bt                      # 查看是谁抛出了异常

段错误 (Segmentation Fault):

(gdb) run
# 程序崩溃后
(gdb) bt                      # 查看崩溃位置
(gdb) print this              # 检查当前对象的 this 指针是否为空或非法

死循环:

(gdb) run
# Ctrl+C 中断
(gdb) bt

实用技巧

# 条件断点
(gdb) break file.cpp:42 if x == 0

# 监视点(值改变时停止)
(gdb) watch variable

# 查看源代码
(gdb) list
(gdb) list Class::Method

# C++ 名称修饰 (Name Mangling)
# GDB 通常会自动处理,手动时可用:
(gdb) set print demangle on

# 查看虚函数表 (Virtual Table) - 进阶
(gdb) info vtbl object_ptr

典型调试场景示例

# 1. 调试 STL 容器崩溃
g++ -g program.cpp -o program
gdb ./program
(gdb) run
# 收到 SIGSEGV
(gdb) bt
(gdb) frame 0
(gdb) print myVector          # 查看 vector 状态(需 GDB pretty printers)
(gdb) print myVector.size()   # 有时可直接调用简单方法(慎用)

# 2. 调试类成员逻辑
(gdb) break MyClass::process
(gdb) run
(gdb) next
(gdb) print this->m_value     # 检查成员变量
(gdb) set var m_value = 10    # 修改成员变量测试

© 2026 myfk. All rights reserved.