在docker容器中生成core dump文件
基础概念core dump在绝大多数GNU/Linux系统中,当应用程序发生没有捕获的异常信号ARORT/SEGV时,系统会终止当前进程,并生成core dump文件,它一般在程序执行的主目录下,通常命名为core或者core.PID。通常情况下core dump包含了程序运行时的内存,寄存器状态,堆栈指针,内存管理信息等。在实际的开发场景中,这些信息能够对开发人员调试定位问题提供非常大...
基础概念
core dump
在绝大多数GNU/Linux系统中,当应用程序发生没有捕获的异常信号ARORT/SEGV时,系统会终止当前进程,并生成core dump文件,它一般在程序执行的主目录下,通常命名为core
或者core.PID
。通常情况下core dump包含了程序运行时的内存,寄存器状态,堆栈指针,内存管理信息等。在实际的开发场景中,这些信息能够对开发人员调试定位问题提供非常大的帮助,所以在特定场合生成并留存core dump是一件必要而有意义的事情。ulimit
ulimit是GNU/Linux的一个命令行工具,用于显示或设置用户可以使用的资源限制。在本例中,我们主要关注core文件大小限制的设置或查看。
使用ulimit -c
查看对core文件大小的限制,例如:
# ulimit -c
unlimited
unlimited
表示没有限制,这意味着当应用程序异常时,系统能够输出任意大小的core dump文件,如果结果是非零数字,则表示系统只能输出限制大小的core dump文件,如果结果为零,则系统不会输出core dump文件。
设置对core文件大小的限制,如:
# ulimit -c unlimited 不限制
# ulimit -c 1024 限制大小为1024
# ulimit -c 0 限制大小为0,即不输出core文件
- docker ulimit
在docker容器中,应用程序随着容器的启动而启动,我们要想在应用程序启动之初就设置好ulimit的设置,可以通过docker run
中的--ulimit
参数进行设置。
实验步骤
知道了以上基础概念之后,我们可以开始尝试在docker容器中生成core dump文件了,步骤如下:
1、启动容器
docker run -it -d --name=core-dump-test --ulimit core=-1 ubuntu:12.04 /bin/sleep 3600
2、进入容器
docker exec -it core-dump-test bash
3、在容器中查看core文件大小限制
# ulimit -c
unlimited
说明没有core文件大小限制。
3、触发当前shell终端的段错误
kill -s SIGSEGV $$
此时你会发现你刚刚执行的shell终端已经关闭。
4、重新进入容器
docker exec -it core-dump-test bash
查看生成的core文件:
ls | grep core
你会在当前目录下发现刚刚生成的core文件。
最佳实践
在容器中调试应用程序
在这种方式下,你可以按如下方式启动容器,然后进入容器里边进行gdb调试:
docker run -it -d --name=core-dump-test --ulimit core=-1 --security-opt seccomp=unconfined ubuntu:12.04 bash
在这种方式下,docker容器的主进程是bash,你可以再容器里边调试你自己的应用程序,你自己的应用程序中断不会导致容器的退出,生成的core dump默认就在你应用程序启动的主路径下,调试起来非常方便。
在其他环境调试应用程序
在实际的应用场景中,更多的情况下,你的应用程序是作为容器主进程的,当应用程序崩溃的时候,容器也会退出,你基本上很难在容器进行调试。另外,线上容器一般比较精简,肯能不包含你的所需的调试工具,所以你可能需要在其他环境下进行相关调试,那么就需要获取到相关的core dump文件。
1、从容器中拷贝core dump文件
如果你明确知道你的应用程序的core dump文件名称和位置,那么你可以从容器中直接拷贝core dump文件,即使这个容器已经异常退出。例如,core dumo文件在容器core-dump-test
中的/tmp/cores
路径下,名为core.1
,那么你可以用如下命令将core dump拷贝到当前主机的当前目录:
docker cp core-dump-test:/tmp/cores/core.1 .
2、通过目录挂载方式将core dump文件输出到主机目录
通常情况下,你可能既不知道core dump文件的路径在哪里,也不知道core dump文件的确切名称是什么,所以你可能需要设置core dump的输出路径和文件命名规则,并将该路径挂载到本机,实现core dump文件自动输出到主机目录,然后你就可以拿这些core dump文件大大展身手,进行你想要的调试了。
设置core dump文件的输出路径
在主机上执行如下命令:
echo "/tmp/cores/core.%p" > /proc/sys/kernel/core_pattern
以上,将core dump的输出路径修改为/tmp/cores
,后续容器中的应用程序core dump文件也将输出到容器的/tmp/cores
文件,因为在容器中读取的/proc/sys/kernel/core_pattern
文件实质上就是主机的/proc/sys/kernel/core_pattern
文件。
下边,我们将容器的/tmp/cores
挂载到主机的/var/tmp/cores
,那么容器中生成的core dump文件将自动输出到主机的/var/tmp/cores
目录。docker容器的启动示例如下:
docker run -it -d --name=core-test --ulimit core=-1 -v /var/tmp/cores:/tmp/cores core-test:v1 /test/core-test
其中镜像core-test:v1
是基于ubuntu:12.04
镜像构建的一个测试镜像,在/test/core-test
程序中中调用abort()
模拟程序崩溃生成core dump文件。
更多推荐
所有评论(0)