GDB分析core文件必须做对三件事:拿到带调试信息的可执行文件、确认core文件真实有效、用对GDB工具链;其他问题均可按ulimit、core_pattern、suid_dumpable、架构匹配、符号表、栈完整性等步骤排查。

线上程序崩溃后,GDB 分析 core 文件不是“能不能做”,而是“必须做对三件事”:拿到带调试信息的可执行文件、确认 core 文件真实有效、用对 GDB 工具链。其他都是细节。
core 文件没生成?先查 ulimit 和 core_pattern
线上服务崩了却找不到 core,90% 是因为系统默认禁用。别猜,直接验证:
-
ulimit -c输出是0→ 立刻执行ulimit -c unlimited(仅当前会话) -
cat /proc/sys/kernel/core_pattern返回空或none→ 说明路径被重定向或禁用,需补全:echo "/var/core/core-%e-%p-%t" | sudo tee /proc/sys/kernel/core_pattern - 容器环境常见坑:
/var/core目录不存在或权限不足 → 改用/tmp/core(/tmp通常可写)并确保挂载到宿主机 - SUID 程序(如 setuid 的 daemon)可能被内核静默丢弃 core → 检查
cat /proc/sys/fs/suid_dumpable,非 1 需设为1
gdb 加载失败?重点核对三个匹配项
报错 No symbol table is loaded 或 not in executable format,本质是“身份对不上”:
-
file ./my_service和file ./core-xxx必须显示相同架构(如x86_64或aarch64);海光 CPU 要认准Vendor ID: HygonGenuine,选gdb-multiarch或对应交叉 gdb(如gdb-aarch64-linux-gnu) - 可执行文件必须含调试符号:
readelf -S ./my_service | grep debug有输出才可靠;若被strip过,file会标stripped,此时只能靠 debuginfo 包(如my_service-debuginforpm)或重新编译加-g - core 文件必须来自该次构建的二进制:哪怕只改一行代码重新编译,旧 core 也大概率无法还原源码行号
bt 看不到源码行?立刻检查信号类型和栈完整性
输入 bt 只显示一堆 ?? 或 libc 地址,说明栈已损坏或符号缺失。先定位关键线索:
-
info signals SIGSEGV→ 若状态是Stop + Print,说明是真实段错误,崩溃点大概率就是问题源头;若SIGABRT状态是Stop + Print + Pass,说明堆已被提前破坏,bt显示的是“发现者”而非“肇事者” -
thread apply all bt→ 多线程服务中,真正出问题的线程往往栈帧异常(如第 0 帧是__libc_malloc或地址全是0x0000000000000000),而非整齐的业务函数调用链 -
info registers→ 查看rip(指令指针)是否落在合法代码段;rdi/rsi是否为明显非法值(如0x0、0xffffffffffff0000) -
x/20i $rip-20→ 反汇编崩溃点附近指令,确认是不是在执行mov %rax,(%rbx)类型的写操作,且%rbx为空
线上环境不能装 gdb?用 gdb-multiarch 或静态链接版
生产服务器常不装开发工具,但分析不能停:
- 开发机上用
gdb-multiarch(Debian/Ubuntu)或gdb-aarch64-linux-gnu(ARM64)加载线上 core,只要二进制和 core 架构一致,完全可行 - 若连
gdb-multiarch都没有,可下载静态编译版 gdb(如gdb-static),它不依赖系统 glibc,解压即用 - 绝对避免在生产机上临时
yum install gdb—— 可能触发依赖升级,影响运行时环境 - core 文件本身不敏感,但可执行文件可能含密钥或路径信息,传回开发机前建议
strip --strip-all ./my_service(保留调试段,仅删符号表)
最易被忽略的一点:线上 core 文件时间戳(%t)是秒级 UNIX 时间,不是本地时区。用 date -d @1753169522 才能准确对齐告警时间——很多人卡在这一步,以为 core 不是那次崩溃产生的。


















