dotnet诊断工具记录

dotnet-counters

CPU爆高(cpu陡增,比如正常运行一般是x%的cpu,突然到了20% 30%甚至更高)

调试高 CPU 使用率

dotnet tool install --global dotnet-counters
# 和dotnet-trace配合使用收集dotnet程序信息,参见https://docs.microsoft.com/zh-cn/dotnet/core/diagnostics/debug-highcpu?tabs=windows
dotnet-trace ps # 获取pid
dotnet-counters monitor --refresh-interval 1 -p 22884 # 监视CPU使用率
dotnet-trace collect -p 22884 --providers Microsoft-DotNETCore-SampleProfiler  # --providers 是指定了所需的提供程序,是微软提供的应用程序,也可以不写
# 上一步收集,将收集.nettrace文件,可以使用vs 2022直接打开或者PerfView打开(推荐vs 2022)
# 打开后将会展示出CPU占比,自己忽略掉system等系统路径,查看到自己的代码路径,然后定位具体方法

dotnet-coverage

dotnet-dump

内存泄漏(内存飙高或者出现oom)

调试内存泄露

dotnet tool install --global dotnet-dump # dotnet-counters 和 dotnet-dump 结合使用,也可以不进行监视,直接收集转储文件
dotnet-counters monitor --refresh-interval 1 -p 4807 # 查看GC Heap Size (MB) 这一行 ,可以忽略
dotnet-dump collect -p 4807 # 收集转储文件
dotnet-dump analyze core_20190430_185145 # 加载转储的文件
dumpheap -stat # 查看托管堆的整体状态,找到最后几行,给出的结果会按照从小到大排序,所以不用再往上面翻了
# 结果有四列 MT、Count、TotalSize、Class Name,查看TotalSize和Count最大的几个,然后用MT来做下一步
dumpheap -mt 00007faddaa50f90 # 查看当前MT对应的Class Name列表
# 输出结果Address、MT、Size ,然后用Address来做下一步
# 对Class Name实例使用 gcroot 命令,以查看对象的根方式和原因
gcroot -all 00007f6ad09421f8 # 可以将上一步的Address多查看几个,特别是size不同的,以免漏掉一些内存泄漏的地方
# 查看最后输出的HandleTable内容,一般就是自己所要查看内存泄漏的堆栈信息

死锁(无响应或线程累积问题)

调试 .NET Core 中的死锁

dotnet-dump collect -p 4807
dotnet-dump analyze  ~/.dotnet/tools/core_20190513_143916
threads # 如果确定已经线程飙高了,这句话可以不执行
clrstack -all # 如果确定已经线程飙高了,这句话可以不执行
syncblk # 找出实际持有监视器锁定的线程

将会出现类似于下面这种的输出,其中查看Thread这一列,对齐可以有问题,自己要看好Thread指的是死锁所在的线程ID

Index   SyncBlock            MonitorHeld Recursion            Owning Thread  Info          SyncBlock Owner
   43 00000246E51268B8          603         1 0000024B713F4E30 5634  28   00000249654b14c0 System.Object
   44 00000246E5126908            3         1 0000024B713F47E0 51d4  29   00000249654b14d8 System.Object
-----------------------------
Total           344
CCW             1
RCW             2
ComClassFactory 0
Free            0
setthread 28  # 后面也可以执行一下setthread 29
clrstack # 显示当前线程的调用堆栈
# 将会出现很多输出,去除掉system这一类的行,只看自己代码的行,基本就可以找到造成死锁的方法了

dotnet-gcdump

dotnet-trace

dotnet-stack

dotnet-symbol

dotnet-sos

堆栈溢出(StackOverflowException)

调试 StackOverflow 错误

dotnet tool install --global dotnet-sos
set DOTNET_DbgEnableMiniDump=1 # 注意,windows这个地方需要改成set不能使用export ,重新set为0的话,可以还原设置
dotnet run # 运行dotnet程序
dotnet-sos install # 安装 SOS 扩展
# ps windows上安装lldb失败,编译的时候报了282个未找到,我直接放弃 
# 链接地址 https://github.com/dotnet/diagnostics/blob/main/documentation/building/windows-instructions.md ,有兴趣的同学可以自己试试,成功了告诉我

dotnet-dsrouter

windbg(取自一线码农)

下载地址

云盘:https://pan.baidu.com/s/1VqXVIGVHxAZVPNds1525Jg 提取码:mahg

外网:http://www.33lc.com/soft/96743.html

配置微软公有符号

点击File=>Symbol File Path=>框内输入SRV*C:\mysymbols*http://msdl.microsoft.com/download/symbols=>点击OK保存

clr.dll/coreclr.dll、sos.dll

在netcore中,clr的名字变成了 coreclr.dll,路径: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\x.x.x
netcore3.0开始,sos就没有放在版本号文件下了,需要自己手动进行install
dotnet tool install -g dotnet-sos
dotnet-sos install # 将会输出sos.dll路径
# 记住这两个路径

加载dump

在其他地方生成的dump,可以使用File=>Open Crash Dump=>选择dump文件打开
打开后如下图所示,其中0:000>后面的框就是要输入的命令框,输入上面的clr.dll/coreclr.dll、sos.dll
.load C:\Program Files\dotnet\shared\Microsoft.NETCore.App\x.x.x\coreclr.dll
.load load C:\Users\user\.dotnet\sos\sos.dll

windbg(.net fw 4.7.2 x86)

  1. 使用C:\Windows\SysWOW64\taskmgr.exe打开的任务管理器进行dmp转储
  2. WDK 下载中找到对应自己电脑版本的WDK,然后下载安装
  3. 加载dump后,执行一下
.load C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll
.load C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll

命令

CPU爆高一般从线程找原因,看哪个线程死锁或者死循环导致
!t 查看线程,注意Lock
~*e !clrstack 观察各个线程都在做什么
~85s 切换到85线程
!clrstack 查看85线程堆栈

内存爆高从堆栈找,看看那些对象没有释放、有一种特殊情况是线程数爆高,导致内存溢出,此时要分析线程稳定时的内存变化,是否周期性或者持续增长不跌
还有就是托管内存和非托管内存,暂时我也没摸透什么意思
!address -summary 内存使用的归类信息
!dumpheap -stat 
多从https://www.cnblogs.com/huangxincheng/tag/windbg/这个地方看看,找到符合自己的问题原因
posted @ 2022-09-07 10:06  spatxos  阅读(293)  评论(0编辑  收藏  举报