ubuntu coredump 环境配置操作指南
1. 概述
本文档说明如何配置 Linux coredump 环境,用于捕获程序崩溃时的核心转储文件,便于使用 gdb 进行问题定位。
coredump 是程序崩溃时的内存快照,包含崩溃时的寄存器状态、堆栈信息等,对于分析引擎崩溃问题至关重要。
2. 配置步骤
2.1 基础环境检查
bash
# 检查当前coredump配置
cat /proc/sys/kernel/core_pattern
ulimit -c
2.2 方法一:systemd-coredump(推荐)
2.2.1 安装 systemd-coredump
bash
sudo apt-get update
sudo apt-get install -y systemd-coredump
2.2.2 配置文件
systemd coredump 配置 /etc/systemd/coredump.conf:
ini
[Coredump]
Storage=external
MaxSize=50G
KeepFree=10G
ProcessSizeMax=100G
Compress=yes
2.2.3 内核 core_pattern 配置
bash
# 临时设置(重启失效)
sudo sysctl -w kernel.core_pattern="|/lib/systemd/system/systemd-coredump@%i.service"
# 持久化配置
echo 'kernel.core_pattern=|/lib/systemd/system/systemd-coredump@%i.service' | \
sudo tee /etc/sysctl.d/99-coredump.conf
2.2.4 启用服务
bash
# 启用socket(socket-activated方式,按需启动)
sudo systemctl enable systemd-coredump.socket
sudo systemctl start systemd-coredump.socket
2.2.5 设置进程资源限制
bash
# 临时设置(当前会话)
ulimit -c unlimited
# 持久化设置
echo '* soft core unlimited' | sudo tee /etc/security/limits.d/coredump.conf
echo '* hard core unlimited' | sudo tee -a /etc/security/limits.d/coredump.conf
2.3 方法二:文件模式(简单测试用)
文件模式更简单可靠,适合快速验证和内网服务器。
bash
# 设置core文件输出到指定目录
sudo sysctl -w kernel.core_pattern="/tmp/core.%e.%p.%t"
# 创建目录并设置权限
sudo mkdir -p /tmp
sudo chmod 1777 /tmp
# 设置文件大小限制
ulimit -c unlimited
文件名格式说明
| 格式符 | 说明 |
|---|---|
%e |
可执行文件名 |
%p |
进程PID |
%t |
时间戳(秒) |
%u |
用户UID |
%g |
用户GID |
%h |
主机名 |
3. Docker 容器内 coredump 配置
引擎运行在 Docker 容器内时,需要额外配置:
3.1 容器启动参数
bash
sudo docker run -it --privileged \
--ulimit core=unlimited \
--cap-add=SYS_ADMIN \
--cap-add=PERFMON \
--network host \
...其他参数...
easzlab.io.local:5000/lyserver-builder:2.3 /bin/bash
关键参数说明:
--ulimit core=unlimited: 允许容器生成任意大小的core文件--privileged: 获取完整系统权限(性能分析需要)--cap-add=SYS_ADMIN: 系统管理能力(用于性能分析工具)
3.2 宿主机捕获
容器内进程崩溃时,core文件会写入宿主机,被内核的 core_pattern 捕获。确保宿主机已完成上述配置。
4. 验证配置
4.1 编写测试程序
创建 /tmp/test_crash.c:
c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
void trigger_null_pointer_crash() {
int *ptr = NULL;
printf("About to dereference NULL pointer...\n");
*ptr = 42; // SIGSEGV here
}
int main(int argc, char *argv[]) {
printf("=== Coredump Test ===\n");
printf("PID: %d\n", getpid());
if (argc > 1 && strcmp(argv[1], "null") == 0) {
trigger_null_pointer_crash();
}
return 0;
}
4.2 编译和测试
bash
# 编译(带调试符号)
cd /tmp
gcc -g -O0 -o test_crash test_crash.c
# 设置ulimit
ulimit -c unlimited
# 触发崩溃
./test_crash null
4.3 验证结果
方法一(systemd-coredump):
bash
# 查看所有coredump记录
coredumpctl list
# 查看最新coredump详情
coredumpctl info
# 使用gdb分析
coredumpctl debug <PID>
方法二(文件模式):
bash
# 检查core文件
ls -la /tmp/core.*
# 使用gdb分析
gdb /tmp/test_crash /tmp/core.test_crash.12345.1234567890
(gdb) bt
5. 使用 gdb 分析 core 文件
5.1 加载 core 文件
bash
# 方法1:直接加载
gdb /path/to/executable /path/to/corefile
# 方法2:在gdb内加载
gdb
(gdb) file /path/to/executable
(gdb) core-file /path/to/corefile
5.2 常用调试命令
| 命令 | 简写 | 说明 |
|---|---|---|
backtrace |
bt |
显示调用堆栈 |
backtrace full |
bt full |
显示完整堆栈(包含局部变量) |
frame N |
f N |
切换到第N个栈帧 |
info locals |
显示当前栈帧的局部变量 | |
info args |
显示当前函数参数 | |
print var |
p var |
打印变量值 |
x/64x addr |
十六进制查看内存 |
5.3 分析示例
(gdb) bt
#0 0x00005c8d1e9671f0 in trigger_null_pointer_crash () at test_crash.c:10
10 *ptr = 42; // SIGSEGV here
#1 0x00005c8d1e9673ee in main (argc=2, argv=0x7ffd2bc83f88) at test_crash.c:47
崩溃定位结果:
- 崩溃发生在
trigger_null_pointer_crash()函数 - 文件
test_crash.c第10行 - 代码为
*ptr = 42;(空指针解引用) - 由
main()函数在第47行调用
6. 加载调试符号
如果 gdb 显示 [unknown] 而非函数名,需要加载调试符号:
bash
# 在gdb内设置符号路径
(gdb) symbol-file /path/to/library.with.debug
# 或者加载可执行文件和符号
(gdb) file /path/to/executable
(gdb) add-symbol-file /path/to/library.debug 0x...
# 查看是否加载成功
(gdb) info sharedlibrary
7. 多线程程序分析
如果是多线程程序崩溃:
bash
# 查看所有线程
(gdb) info threads
# 切换到指定线程
(gdb) thread N
# 查看所有线程堆栈
(gdb) thread apply all bt
8. 常见问题
8.1 core_pattern 配置正确但无 core 文件
检查资源限制:
bash
ulimit -c
# 如果显示0,需要设置为 unlimited
ulimit -c unlimited
8.2 core 文件过大被截断
在 /etc/systemd/coredump.conf 中增加限制:
MaxSize=100G
8.3 gdb 显示 unknown
需要加载对应的调试符号文件(.debug 或带调试信息的库文件)。
8.4 程序启动时设置了 setrlimit
如果程序内部调用 setrlimit(RLIMIT_CORE, ...) 禁用了core,需要在代码中移除或修改。
9. coredumpctl 命令参考
bash
# 列出所有coredump
coredumpctl list
# 显示coredump信息
coredumpctl info [PID]
# 调试coredump
coredumpctl debug [PID]
# 删除coredump
coredumpctl delete [PID]
# 清空所有coredump
coredumpctl purge
# 后台转储(用于大文件)
coredumpctl dump PID > core.file
10. 快速参考
bash
# 一行命令验证配置(文件模式)
ulimit -c unlimited && (echo 'int main(){int*p=0;*p=1;}' | gcc -x c - -o /tmp/t && /tmp/t)
# 清理测试文件
rm -f /tmp/test_crash /tmp/test_crash.c /tmp/core.*
11. 安全注意事项
- 权限控制: core文件可能包含敏感信息(密码、密钥等),确保目录权限正确
- 磁盘空间: 大型程序的core文件可能很大(几十GB),确保有足够空间
- 自动清理 : 设置合理的
MaxSize和KeepFree,避免磁盘耗尽 - 调试完成后删除: 使用完core文件后及时清理