GDB 调试与 Core Dump 段错误排查指南(Linux/C/C++)
在 Linux 环境下使用 GDB 调试器和 Core Dump 机制排查 C/C++ 程序段错误的完整流程。内容涵盖编译时添加调试信息的必要性、GDB 常用命令速查、实战定位 SIGSEGV 崩溃的方法、Core Dump 文件的生成与分析技巧,以及常见段错误原因总结。通过现场调试和事后分析两种场景,帮助开发者高效还原崩溃现场,定位空指针、野指针及内存越界等问题。

在 Linux 环境下使用 GDB 调试器和 Core Dump 机制排查 C/C++ 程序段错误的完整流程。内容涵盖编译时添加调试信息的必要性、GDB 常用命令速查、实战定位 SIGSEGV 崩溃的方法、Core Dump 文件的生成与分析技巧,以及常见段错误原因总结。通过现场调试和事后分析两种场景,帮助开发者高效还原崩溃现场,定位空指针、野指针及内存越界等问题。

GDB(GNU Debugger)是 Linux 平台最常用的程序调试器之一,主要用来:
bt/where),快速定位问题入口。适用场景:段错误(SIGSEGV)、非法访问、野指针、栈溢出、数组越界、use-after-free 等。
调试/分析崩溃时,可执行文件与崩溃现场必须匹配(同版本、同编译产物)。建议:
# 推荐:关闭过度优化,保留调试信息
gcc -g -O0 main.c -o app
# 或者 C++
g++ -g -O0 main.cpp -o app
-g:生成调试符号(行号、变量名、函数名)-O0 / -Og:降低优化程度,避免变量被优化掉导致 <value optimized out># 方式 1:直接调试可执行文件
gdb ./app
# 方式 2:带参数启动(也可在 gdb 内 set args)
gdb --args ./app arg1 arg2
# 方式 3:调试 core 文件(事后分析)
gdb ./app /path/to/core
# 或
gdb -c /path/to/core ./app
| 命令 | 缩写 | 作用 |
|---|---|---|
break <位置> | b | 设置断点(行号/函数名/文件:行号) |
info breakpoints | i b | 查看断点列表 |
delete <编号> | d | 删除断点 |
run | r | 启动程序(命中断点会停住) |
continue | c | 继续运行到下一个断点/结束 |
next | n | 单步执行(不进入函数) |
step | s | 单步执行(进入函数) |
finish | 跑完当前函数并返回到上一层 | |
until | u | 运行到指定行/跳出循环场景常用 |
quit | q | 退出 gdb |
常见断点位置写法:
(gdb) b main
(gdb) b 20
(gdb) b main.c:20
(gdb) b foo if x > 10
| 命令 | 缩写 | 作用 |
|---|---|---|
list | l | 显示源代码(可 l 1 从第 1 行) |
where / backtrace | bt | 查看调用栈 |
bt full | 调用栈 + 每帧局部变量(core 分析很有用) | |
frame <n> | f | 切换到第 n 层栈帧 |
up / down | 在栈帧之间上下移动 | |
print <表达式> | p | 打印变量/表达式值 |
display <表达式> | 每次停住自动打印 | |
info locals | 打印当前栈帧所有局部变量 | |
info args | 打印当前函数参数 | |
info registers | 查看寄存器 |
x(examine)用于按格式查看内存:
# x/<数量><格式><单位> <地址>
(gdb) x/16xb ptr # 16 字节,按 16 进制 byte 显示
(gdb) x/8xw ptr # 8 个 word(4 字节),按 16 进制显示
(gdb) x/s ptr # 按字符串显示
(gdb) x/i $pc # 反汇编当前指令
main.c:
#include<stdio.h>
#include<stdlib.h>
int main(){
int *p = NULL;
*p = 123; // 对 NULL 解引用,触发段错误
return 0;
}
编译运行:
gcc -g -O0 main.c -o app
./app
gdb ./app
在 gdb 中:
(gdb) run
Program received signal SIGSEGV, Segmentation fault.
(gdb) bt
#0 main () at main.c:7
(gdb) list
(gdb) info locals
(gdb) p p
$1 = (int *) 0x0
这类问题的定位套路:
bt 看栈:崩溃点在哪个函数、哪一行。frame/list 看上下文:看崩溃行附近逻辑。p/info locals/info args:确认关键指针、数组下标、长度参数是否异常。当程序崩溃时,系统可把当时的内存映射、寄存器、栈等信息写入 core 文件,用于事后分析。
# 查看当前限制(0 表示不生成)
ulimit -c
# 临时开启(当前 shell 生效)
ulimit -c unlimited
core 文件路径与命名常由内核参数控制:
cat /proc/sys/kernel/core_pattern
注意:线上环境经常被 systemd 接管 core,core 可能不落在当前目录。需要结合发行版策略确认落盘位置。
假设生成了 core 文件:
gdb ./app core
高频排查命令:
(gdb) bt
(gdb) bt full
(gdb) info threads
(gdb) thread apply all bt
(gdb) frame 0
(gdb) info locals
(gdb) info args
(gdb) p some_ptr
(gdb) x/32xb some_ptr
如果看到类似提示:
no debugging symbols found:二进制没有 -g 调试符号warning: core file may not match specified executable file:core 与可执行文件版本不匹配段错误本质:访问了不允许访问的内存区域(地址不存在或受保护)。典型原因:
char *p = NULL; *p = 'x';sprintf 等导致溢出(建议 snprintf)b main 或 b 可疑函数n/sp、info locals、info argsgdb ./app corebt full 一步到位获取:崩溃行 + 参数 + 局部变量x/ 查看指针指向内存是否合理info threads + thread apply all bt如果出现:<value optimized out>
-O0 或 -Og-g# 让长数组/长字符串完整打印(默认可能截断)
(gdb) set print elements 0
# 打印结构体更友好
(gdb) set print pretty on
# 查看动态库与映射
(gdb) info sharedlibrary
(gdb) info proc mappings
-g、尽量 -O0/-Og,能显著提升定位效率。bt → list → info locals/args → p/x 的套路。
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online