C/C++高级调试技巧
一、GDB高级调试
1. 断点调试
gdb
# 设置断点
break main.cpp:100
# 设置条件断点
break main.cpp:100 if i == 10
# 设置观测点
gwatch x == 10
# 设置硬件断点
hbreak main.cpp:100
# 继续执行
continue
# 单步执行
next
# 单步进入函数
step
# 查看变量
print x
# 查看内存
x/10xw &x2. 汇编级调试
gdb
# 查看汇编代码
disassemble main
# 查看特定函数的汇编代码
disassemble function_name
# 设置断点在汇编指令上
break *0x4005e6
# 单步执行汇编指令
si3. 调试多进程/多线程
gdb
# 调试子进程
es follow-fork-mode child
# 查看线程列表
info threads
# 切换到指定线程
thread 2
# 设置线程断点
brake main.cpp:100 thread 2
# 查看线程栈
thead apply all bt多线程死锁定位实战(从 mutex 地址反查 LWP、在信号 handler 中定位死锁闭环):见 GDB 定位信号 handler 死锁。
4. 高级GDB命令
gdb
# 保存断点
save breakpoints breakpoints.txt
# 加载断点
source breakpoints.txt
# 执行shell命令
shell ls -l
# 编辑代码
ed main.cpp
# 重新加载调试文件
target remote localhost:1234二、Core dump的高级分析
1. 生成Core dump文件
bash
# 启用Core dump
sudo sysctl -w kernel.core_pattern=core.%e.%p.%t
# 设置Core dump文件大小限制
ulimit -c unlimited2. 分析Core dump文件
gdb
# 加载可执行文件和Core dump文件
gdb ./your_program core.12345
# 查看调用栈
bt
# 查看线程调用栈
tbt
# 查看局部变量
info locals
# 查看寄存器
i r
# 查看内存
x/10xw &x
# 反汇编代码
disassemble3. 离线分析Core dump
bash
# 使用crash工具分析Core dump
sudo crash /usr/lib/debug/boot/vmlinux-$(uname -r) core.12345
# 使用gdb分析Core dump
gdb ./your_program core.12345三、内存泄漏与内存碎片的量化分析
1. 内存泄漏检测工具
bash
# 使用valgrind检测内存泄漏
valgrind --leak-check=full ./your_program
# 使用asan检测内存泄漏
clang -fsanitize=address -g ./your_program
./your_program
# 使用tsan检测线程竞争
clang -fsanitize=thread -g ./your_program
./your_program2. 内存碎片分析
bash
# 查看内存碎片情况
cat /proc/buddyinfo
# 查看Slab分配器信息
cat /proc/slabinfo
# 查看内存使用情况
free -m
# 查看内存节点信息
numactl --hardware3. 内存碎片量化分析
cpp
#include <malloc.h>
#include <stdio.h>
int main() {
// 查看内存碎片情况
struct mallinfo info = mallinfo();
printf("Total non-inuse space: %d bytes\n", info.fordblks);
printf("Total free chunks: %d\n", info.ordblks);
return 0;
}四、参考资料
- GDB官方文档:https://sourceware.org/gdb/documentation/
- 《GDB调试指南》 陈莉君
- 《C++调试实战》 布鲁斯·莫罗
- https://www.kernel.org/doc/html/latest/admin-guide/mm/
- https://man7.org/linux/man-pages/man3/mallinfo.3.html
五、一句话总结
C++ 调试用 GDB 条件断点/观测点控制执行,崩溃时靠 core dump(配 core_pattern、ulimit)留现场,再 gdb 加载用 bt 定位栈;线上须保留调试符号才能还原。