其他
生产崩溃事后排查:启用/收集 core dump 并用…
当程序在生产环境崩溃并留下 core 文件,或需要在不重跑程序的情况下从 core 提取调用栈、寄存器、局部变量并解析符号时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 48/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 56/100 ×0.15
适用场景
生产崩溃事后排查:启用/收集 core 通用
解决思路
- Linux 临时启用 core dump:运行 ulimit -c unlimited(登出后失效)。
- Linux 持久启用 core dump:在 /etc/security/limits.conf 添加 * soft core unlimited 和 * hard core unlimited。
- 检查当前 core dump 限制:运行 ulimit -c。
- 设置 core 文件名和位置:运行 sudo sysctl -w kernel.core_pattern=/tmp/core-%e-%p-%t;其中 %e 表示可执行文件,%p 表示 PID,%t 表示时间戳。
- 持久设置 core pattern:在 /etc/sysctl.d/99-core.conf 添加 kernel.core_pattern=/tmp/core-%e-%p-%t 和 kernel.core_uses_pid=1。
- 在 systemd 管理的 Linux 上列出最近崩溃:运行 coredumpctl list。
- 显示最近一次崩溃的详细信息:运行 coredumpctl info。
- 在 GDB 中加载最近一次崩溃:运行 coredumpctl gdb。
- 在 GDB 中加载指定 PID 的崩溃:运行 coredumpctl gdb 12345。
- 导出 core 文件:运行 coredumpctl dump -o myapp.core PID。
- 确认 systemd core 存储位置:/var/lib/systemd/coredump/。
- macOS 启用 core dump:运行 ulimit -c unlimited;macOS 默认使用 /cores,且需 root 可写。
- 检查 macOS core 文件:运行 ls /cores/。
- 对于 launchd 启动的服务,在 plist 中设置 HardResourceLimits 的 Core 为 9223372036854775807。
- 用 GDB 加载二进制和 core:运行 gdb ./prog core.12345。
- 如果二进制被 strip,提供未 strip 的副本:运行 gdb ./prog-with-symbols core.12345。
- GDB 首要命令:运行 bt 查看调用栈。
- GDB 首要命令:运行 bt full 查看调用栈和局部变量。
- GDB 首要命令:运行 info registers 查看崩溃时 CPU 状态。
- GDB 首要命令:运行 frame 2 跳转到感兴趣的帧。
- GDB 首要命令:运行 info locals 查看该帧局部变量。
- GDB 首要命令:运行 print ptr 检查指针。
- 多线程崩溃时:在 GDB 中运行 thread apply all bt full。
- 用 LLDB 加载 core:运行 lldb ./prog -c core.12345。
- 或用 LLDB 交互式加载:运行 lldb,然后执行 target create ./prog --core core.12345。
- LLDB 命令:运行 bt。
- LLDB 命令:运行 thread backtrace all。
- LLDB 命令:运行 frame select 2。
- LLDB 命令:运行 frame variable。
- 缺失符号时安装 debuginfod 客户端(Debian/Ubuntu):运行 sudo apt install debuginfod。
- 启用 debuginfod:在 ~/.bashrc 或 /etc/environment 中添加 export DEBUGINFOD_URLS="https://debuginfod.ubuntu.com https://debuginfod.elfutils.org"。
- 设置 DEBUGINFOD_URLS 后,GDB 会自动获取符号:运行 gdb ./prog core。
- 手动查询调试信息:运行 debuginfod-find debuginfo <build-id>。
- 手动查询源码:运行 debuginfod-find source <build-id> /path/to/file.c。
- 手动查找符号时,先检查二进制是否有 build ID:运行 readelf -n ./prog | grep Build。
- 查找正确 debug 包:Debian 上运行 apt install prog-dbg 或 prog-dbgsym。
- 查找正确 debug 包:RPM 上运行 dnf install prog-debuginfo。
- 让 GDB 指向调试符号目录:在 GDB 中运行 set debug-file-directory /usr/lib/debug。
- 或用 eu-readelf 转储 build ID:运行 eu-readelf -n ./prog。
- 再按 build ID 查找 .debug 文件:运行 find /usr/lib/debug -name "*.debug" | xargs eu-readelf -n 2>/dev/null | grep <build-id>。
- strip 二进制并保留符号的最佳实践:用 gcc -g -O2 -o prog main.c 构建。
- 分离调试信息:运行 objcopy --only-keep-debug prog prog.debug。
- 生成 stripped 二进制:运行 objcopy --strip-debug prog prog.stripped。
- 添加 debuglink 让 GDB 自动找到调试文件:运行 objcopy --add-gnu-debuglink=prog.debug prog.stripped。
- 部署 prog.stripped,并将 prog.debug 按 build-id 索引保存在符号库中。
- 从 core 快速分类:非交互打印 backtrace,运行 gdb -batch -ex 'bt full' -ex 'thread apply all bt full' ./prog core 2>&1 | tee crash.txt。
- 从 core 快速分类:打印寄存器,运行 gdb -batch -ex 'info registers' ./prog core。
- 从 core 快速分类:检查导致崩溃的信号,运行 gdb -batch -ex 'info signal' ./prog core。
- 完整速查表参见 references/cheatsheet.md。
适用边界 · 注意事项
- 无法获取崩溃程序对应的二进制或与 build-id 匹配的调试符号时,完整回溯、源码和局部变量可能不可得。
- 系统或容器策略禁止生成 core dump,或未提前调整 ulimit/core_pattern/coredumpctl,则生产崩溃后可能没有 core 文件可分析。
- 目标问题需要实时交互复现或运行时观测时,应改用 GDB/LLDB 附加进程或 sanitizer,而不是仅做 core 事后分析。