dotnet core调试docker下生成的dump文件
最近公司預生產環境.net core應用的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命令,不在贅述了,大家自行研究吧。。。?
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/
原文地址:https://www.cnblogs.com/iamsach/p/10118628.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的dotnet core调试docker下生成的dump文件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微服务架构基础之Service Mesh
- 下一篇: 8分钟学会Consul集群搭建及微服务概