Docker容器Core文件生成
· 阅读需 2 分钟
在 Ubuntu Docker 容器中启用并自定义 Core Dump 的生成路径,涉及容器内部配置和宿主机内核设置两个层面。
这是因为 Core Dump 的处理是由宿主机内核(Kernel)控制的,容器只是共享了宿主机的内核。
内核在生成 Core Dump 时,会根据 /proc/sys/kernel/core_pattern 的设置来决定保存路径。需要执行命令临时生效:
sysctl -w kernel.core_pattern=/tmp/coredumps/core.%e.%t.%p
或修改宿主机上的文件永久生效:
/etc/sysctl.conf
kernel.core_pattern=/tmp/coredumps/core.%e.%t.%p
然后执行:
sysctl -p
备注
这里的路径 /tmp/coredumps 必须在容器内部也存在,或者通过挂载卷映射进去,否则容器进程崩溃时会找不到路径导致生成失败。
在启动容器时,关键是放开 core 文件大小限制(ulimit):
--ulimit core=-1:解除 core 文件大小限制(无限),这是生成 core 的必要条件。- 挂载目录:将宿主机的 core 存放目录映射到容器内,便于从宿主机直接读取。
--cap-add=SYS_PTRACE(可选):仅在需要于容器内用 gdb 实时附加调试时才需要;事后分析 core 文件并不需要它,更无需--privileged。
docker run -d \
--ulimit core=-1 \
-v /tmp/coredumps:/tmp/coredumps \
--name my_ubuntu_container \
ubuntu:latest
测试代码:
#include <stdio.h>
#include <unistd.h> // getpid()
void crash_function() {
printf("准备触发崩溃...\n");
int *ptr = NULL; // 定义一个空指针
*ptr = 10; // 尝试向空指针写入数据,触发段错误
}
int main() {
printf("程序启动,PID: %d\n", getpid());
crash_function();
return 0;
}
编译时加上 -g 保留调试符号:
gcc -g crash.c -o app
运行触发崩溃、得到 Core Dump 文件后,用 gdb 分析:
gdb ./app /tmp/coredumps/core.app.1768486704.127