杀鸡焉用牛刀!放下Windbg,让dotnet-stack来快速定位死锁原因
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了杀鸡焉用牛刀!放下Windbg,让dotnet-stack来快速定位死锁原因相关的知识,希望对你有一定的参考价值。
我们用来分析CPU过高、死锁问题的常见方案是使用Windbg分析dump文件。
但是这种方式存在一些缺点,比如dump文件过大难以下载,windbg使用过于复杂难以掌握等。
这里介绍一个小工具dotnet-stack,帮助我们检查托管代码调用堆栈,快速定位到当前执行的代码,找到问题原因。
准备代码
新建ConsoleApp1,编写如下代码:
static void Main(string[] args)
{
new Program().TestLock();
Console.Read();
}
void TestLock()
{
lock (this)
{
var task = Task.Factory.StartNew(() =>
{
Console.WriteLine("-------开始-------");
Deadlock();
Console.WriteLine("---------完成--------");
});
task.Wait();
}
}
void Deadlock()
{
lock (this)
{
Console.WriteLine("公众号“My IO”");
}
}
示例代码通过抢占lock模拟死锁现象,运行代码后,可以发现命令行停在"-------开始-------"就没有继续输出了。
分析问题
首先,运行下面的命令安装dotnet-stack:
dotnet tool install --global dotnet-stack
然后,我们需要找到死锁程序对应的进程id。虽然可以用任务管理器或者ps
去查看,但是这里可以直接用命令获取:
dotnet-stack ps
拿到ConsoleApp1的进程id6004
,运行下列命令:
dotnet-stack report --process-id 6004
该命令可从进程中收集跟踪的所有堆栈。格式如下:
注释前缀为#
每个线程都有一个包含本机线程ID的头:
Thread (<thread-id>):
托管代码:
模块!方法
非托管代码:
[Native Frames]
从图中可以看到,最后执行到的代码是ConsoleApp1!Program.Deadlock()
,对照代码,就可以轻松找到死锁原因了。
结论
dotnet-stack
麻雀虽小,但是功能不错,用于解决死锁问题还是不错的。
如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我!
以上是关于杀鸡焉用牛刀!放下Windbg,让dotnet-stack来快速定位死锁原因的主要内容,如果未能解决你的问题,请参考以下文章
《Spring 手撸专栏》第 2 章:小试牛刀(让新手能懂),实现一个简单的Bean容器