1. 程式人生 > >dotnet core除錯docker下生成的dump檔案

dotnet core除錯docker下生成的dump檔案

最近公司預生產環境的docker容器經常出現記憶體暴漲現象,有時會突然吃掉幾個G,觸發監控預警,造成容器重啟。

分析了各種可能原因,修復了可能發生的記憶體洩露,經測試本地正常,但是發到預生產還是會有記憶體暴漲現象,反而更改GC模式後記憶體使用保持較低水平,百思不得其解,所以想到使用除錯dump檔案方式來分析應用記憶體狀況。

環境:

lldb:3.9

dotnetcore:2.1.6

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

(根據文件,dotnetcore2.0需要使用lldb3.6,但是我嘗試了沒有成功,lldb使用的dotnetcore版本與dump應用的dotnetcore版本要一致,由於core2.1現在官方只提供2.1.6的runtime檔案,故本次測試使用2.1.6版本,如果哪位童鞋在core2.0上除錯成功了,麻煩告訴我方法)

 

linux下需要使用lldb來進行dump分析,但是安裝這個太慢,所以我找了個安裝好的docker image使用,有興趣的也可以自行安裝,這裡就不介紹安裝過程了,.net core 本身提供了lldb sos 外掛,只要載入使用就好。

啟動一個.net core應用容器,這裡需要多加幾個引數,不然無法建立dump(另外多說一句,docker內crash coredump檔案無法生成也是許可權原因,我這邊啟動時都給了許可權,如果僅僅是需要使用.netcore提供createdump工具,只需要加--privileged=true):

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命令,不在贅述了,大家自行研究吧。。。