dotnet core調試docker下生成的dump文件

最近公司預生產環境.net core應用的docker容器常常出現內存暴漲現象,有時會忽然吃掉幾個G,觸發監控預警,形成容器重啓。linux

分析了各類可能緣由,修復了可能發生的內存泄露,經測試本地正常,可是發到預生產仍是會有內存暴漲現象,反而更改GC模式後內存使用保持較低水平,百思不得其解,因此想到使用調試dump文件方式來分析應用內存情況。git

環境:github

lldb:3.9docker

dotnetcore:2.1.6shell

docker image:microsoft/dotnet:2.1.6-aspnetcore-runtimeubuntu

(根據文檔,dotnetcore2.0須要使用lldb3.6,可是我嘗試了沒有成功,lldb使用的dotnetcore版本與dump應用的dotnetcore版本要一致,因爲core2.1如今官方只提供2.1.6的runtime文件,故本次測試使用2.1.6版本,若是哪位童鞋在core2.0上調試成功了,麻煩告訴我方法)bash

 

linux下須要使用lldb來進行dump分析,可是安裝這個太慢,因此我找了個安裝好的docker image使用,有興趣的也能夠自行安裝,這裏就不介紹安裝過程了,.net core 自己提供了lldb sos 插件,只要加載使用就好。網絡

啓動一個.net core應用容器,這裏須要多加幾個參數,否則沒法建立dump(另外多說一句,docker內crash coredump文件沒法生成也是權限緣由,我這邊啓動時都給了權限,若是僅僅是須要使用.netcore提供createdump工具,只須要加--privileged=true):app

docker run -d -p 80:80 --name dumptest --ulimit core=-1 --security-opt seccomp=unconfined --privileged=true dumptest:v1工具

--ulimit core=-1              不限制coredump大小
--security-opt seccomp=unconfined   容許容器執行所有系統調用
--privileged=true            容許createdump訪問其餘進程

進入容器:

docker exec -it dumptest /bin/bash

建立dump文件:

/usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.6/createdump 1

(經觀察,容器內的跑的應用進程ID都是1,因此直接使用,也能夠使用top命令來查看進程ID,建立dump文件在/tmp/coredump.1)

退出容器:

exit

在宿主機建立文件夾/data/docker,並將容器中的dump文件拷貝到宿主機:

cd /&&mkdir data&&cd data&&mkdir docker

docker cp dumptest :/tmp/coredump.1 /data/docker

拉取lldb鏡像(此鏡像是lldb3.9的dotnetcore版本爲2.1.5,有其餘需求請自行查找):

docker pull yyoda/dotnet-lldb

啓動lldb容器,並將coredump文件路徑映射到容器內(若是想要長期使用不要帶--rm參數):

docker run -d -v /data/docker:/dump --rm -it --name lldb yyoda/dotnet-lldb:latest /bin/bash

鏡像內須要安裝dotnetcore2.1.6,爲了方便安裝,在容器內部使用阿里源:

cd /data/docker
touch sources.list

將下面的源加入sources.list:

deb http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse

進入lldb容器:

docker exec -it lldb /bin/bash

更新源:

mv /dump/sources.list /etc/apt/source.list
apt-get update

安裝dotnetcore2.1.6 runtime(因爲網絡等緣由,若是失敗多試幾回):

wget -q https://packages.microsoft.com/config/ubuntu/14.04/packages-microsoft-prod.deb
dpkg -i packages-microsoft-prod.deb

apt-get install apt-transport-https
apt-get update
apt-get install dotnet-runtime-2.1

啓動lldb:

lldb-3.9 dotnet -c /dump/coredump.1 -o "plugin load /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.6/libsosplugin.so"

(若是sos加載失敗,啓動後輸入命令:plugin load /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.6/libsosplugin.so

   若是runtime加載失敗,啓動後輸入命令:setclrpath /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.6)

輸入soshelp命令,出現下圖:

查看堆上的對象類型分配狀況(因爲結果太多,這裏加入大於1024byte過濾):

dumpheap -stat -min 1024

查看指定類型對象狀況:

dumpheap -mt 00007f2a28b874e8 -min 1024

查看指定對象狀況:

dumpobj 00007f2a1400fc88

 

剩下的就是熟悉sos命令,不在贅述了,你們自行研究吧。。。

 

ps:附上docker容器內應用崩潰時生成dump方法:

1.容器啓動時要帶下面兩個參數:

  --ulimit core=-1 
  --security-opt seccomp=unconfined 

2.宿主機上執行命令,更改dump文件輸出路徑:

  echo '/tmp/core.%t.%e.%p' | sudo tee /proc/sys/kernel/core_pattern

  (由於系統在產生 coredump 文件時是根據 /proc/sys/kernel/core_pattern 的設定模板來的,而默認的設定是 /usr/share/apport/apport %p %s %c %P,也就是用管道傳apport。然而 Docker 裏面的系統不必定有裝 apport,而且 /proc 又是直接掛到 Docker 裏面的,因此須要設置固定存放位置 /tmp。

    %p 所dump進程的進程ID

    %t core dump的時間 

    %e 程序文件名)

測試:

  進入容器後執行 kill -s SIGSEGV $$   觸發當前shell終端的段錯誤。

  再次進入容器,在/temp路徑下能夠看到剛剛生成的dump文件

  

 

參考資料:

https://github.com/mikem8361/coreclr/blob/5c22cb85c7cc9173f2fb783bf24c0cbbb6096c89/Documentation/building/debugging-instructions.md

http://blogs.microsoft.co.il/sasha/2017/02/26/analyzing-a-net-core-core-dump-on-linux/

相關文章
相關標籤/搜索