.NET调试实例-实验1:死锁 (原创翻译)
-原文地址:http://blogs.msdn.com/tess/archive/2008/02/04/net-debugging-demos-lab-1-hang.aspx
这是关于.NET调试的10个实验里的第一个。这个实验的对象是个名叫BuggyBits的站点,就像名字暗示的一样,虫子的攻击是非常凶猛地!(buggy:多虫的, 臭虫成灾的)
开始前,请务必按照前面的安装说明做好准备工作。
我想大家在动手实践的时候可能会遇到很多问题,尽管我会尽可能地多回答留言栏里的问题,但是我不能保证回答所有的问题,所以请大家遇到你们能解答的问题的时候,请尽可能地直言相告。这里还要强调一下,请确保你已经严格遵守了所有的安装说明。
注意:实验中的问题(Q: …)只是定位解决问题时可能会用到的帮助信息。在我发布对应的实验回顾(为了给大家一段没有答案的时间思考,实验回顾大约在原实验发布一周后发布)之前,我将适当地控制一些包含答案的评论。
请大家在评论里畅所欲言,无论好与坏,这样我才能知道在未来的实验里做那些改进。
不多说了,现在我们开始实验1:
重现问题:
1.浏览 http://localhost/BuggyBits/FeaturedProducts.aspx 这个页面将延时5秒显示,你能在页面底部看到开始时间和执行时间。
2.打开5个以上的浏览器同时浏览这个页面,并且同时刷新。
注意每一个页面的执行时间并确保它们的开始时间几乎都完全一样。(如果开始时间不同,你有可能是没有执行那个reg文件)
Q:执行时间怎么样?
Q:问题重现的时候,w3wp.exe进程的CPU利用率怎么样?高还是低?
Q:出现死锁症状的潜在原因是什么?
获取内存转储文件:
1.打开一个命令行窗口,然后进入到你的调试器工具集目录。输入下面的命令行准备获取转储文件,但是暂时先不要执行。
adplus –hang –pn w3wp.exe –quiet
2.重现问题,使用刚才同时刷新5个浏览器的方法或者通过下面的命令行使用tinyget给那个网页施压的方法。
tinyget -srv:localhost -uri:/BuggyBits/FeaturedProducts.aspx -threads:30 -loop:50
3.在刚才的adplus窗口敲回车就可以在所有请求正在执行的时候获得内存转储文件。
Q:adplus处于挂起模式的时候,什么触发了生成内存转储文件?
Q:你需要有什么样的权限才可以获取到一个进程的内存转储文件?
Q:转储文件被创建在那里? 提示:查阅一下Windbg的帮助文件,关于adplus/挂起模式部分。
使用windbg.exe打开转储文件
1.启动Windbg,使用"File/Open Crash dump"菜单打开刚才获得的内存转储文件。
2.设置符号文件的路径 (具体参考:信息和安装说明)
3.加载SOS (具体参考:信息和安装说明)
检查堆栈
1.检查本地调用堆栈
~* kb 2000
2.检查.NET调用堆栈
~* e !clrstack
Q:你是否发现了一些某个线程正在等待其它同步机制的典型迹象或者在调用堆栈上看出某些可能性?
定位并解决死锁
1.确定持有锁的线程的ID.
!syncblk
Q:什么线程拥有锁?
Q:有多少线程在等待解锁?
提示:MonitorHeld = 1时表示这个线程持有锁,MonitorHeld = 2时表示这个线程被阻塞!
2.挑选一个堵塞线程(提示:堵塞线程位于AwareLock::Enter),看看它在做什么?
~5s (切换到线程5)
kb 2000 (检查本地堆栈)
!clrstack (检查.NET堆栈)
Q:堵塞线程等待的锁在那个.NET函数里?
3.检查持有锁的线程在做什么?
~5s (切换到线程5)
kb 2000 (检查本地堆栈)
!clrstack (检查.NET堆栈)
Q:为什么会发生死锁?
4.检查代码,看是否有方法使用了锁,进一步证明你的假设。
提示
下面的文章在定位和解决这个死锁问题的时候可能会用到:
这是关于.NET调试的10个实验里的第一个。这个实验的对象是个名叫BuggyBits的站点,就像名字暗示的一样,虫子的攻击是非常凶猛地!(buggy:多虫的, 臭虫成灾的)
开始前,请务必按照前面的安装说明做好准备工作。
我想大家在动手实践的时候可能会遇到很多问题,尽管我会尽可能地多回答留言栏里的问题,但是我不能保证回答所有的问题,所以请大家遇到你们能解答的问题的时候,请尽可能地直言相告。这里还要强调一下,请确保你已经严格遵守了所有的安装说明。
注意:实验中的问题(Q: …)只是定位解决问题时可能会用到的帮助信息。在我发布对应的实验回顾(为了给大家一段没有答案的时间思考,实验回顾大约在原实验发布一周后发布)之前,我将适当地控制一些包含答案的评论。
请大家在评论里畅所欲言,无论好与坏,这样我才能知道在未来的实验里做那些改进。
不多说了,现在我们开始实验1:
重现问题:
1.浏览 http://localhost/BuggyBits/FeaturedProducts.aspx 这个页面将延时5秒显示,你能在页面底部看到开始时间和执行时间。
2.打开5个以上的浏览器同时浏览这个页面,并且同时刷新。
注意每一个页面的执行时间并确保它们的开始时间几乎都完全一样。(如果开始时间不同,你有可能是没有执行那个reg文件)
Q:执行时间怎么样?
Q:问题重现的时候,w3wp.exe进程的CPU利用率怎么样?高还是低?
Q:出现死锁症状的潜在原因是什么?
获取内存转储文件:
1.打开一个命令行窗口,然后进入到你的调试器工具集目录。输入下面的命令行准备获取转储文件,但是暂时先不要执行。
adplus –hang –pn w3wp.exe –quiet
2.重现问题,使用刚才同时刷新5个浏览器的方法或者通过下面的命令行使用tinyget给那个网页施压的方法。
tinyget -srv:localhost -uri:/BuggyBits/FeaturedProducts.aspx -threads:30 -loop:50
3.在刚才的adplus窗口敲回车就可以在所有请求正在执行的时候获得内存转储文件。
Q:adplus处于挂起模式的时候,什么触发了生成内存转储文件?
Q:你需要有什么样的权限才可以获取到一个进程的内存转储文件?
Q:转储文件被创建在那里? 提示:查阅一下Windbg的帮助文件,关于adplus/挂起模式部分。
使用windbg.exe打开转储文件
1.启动Windbg,使用"File/Open Crash dump"菜单打开刚才获得的内存转储文件。
2.设置符号文件的路径 (具体参考:信息和安装说明)
3.加载SOS (具体参考:信息和安装说明)
检查堆栈
1.检查本地调用堆栈
~* kb 2000
2.检查.NET调用堆栈
~* e !clrstack
Q:你是否发现了一些某个线程正在等待其它同步机制的典型迹象或者在调用堆栈上看出某些可能性?
定位并解决死锁
1.确定持有锁的线程的ID.
!syncblk
Q:什么线程拥有锁?
Q:有多少线程在等待解锁?
提示:MonitorHeld = 1时表示这个线程持有锁,MonitorHeld = 2时表示这个线程被阻塞!
2.挑选一个堵塞线程(提示:堵塞线程位于AwareLock::Enter),看看它在做什么?
~5s (切换到线程5)
kb 2000 (检查本地堆栈)
!clrstack (检查.NET堆栈)
Q:堵塞线程等待的锁在那个.NET函数里?
3.检查持有锁的线程在做什么?
~5s (切换到线程5)
kb 2000 (检查本地堆栈)
!clrstack (检查.NET堆栈)
Q:为什么会发生死锁?
4.检查代码,看是否有方法使用了锁,进一步证明你的假设。
提示
下面的文章在定位和解决这个死锁问题的时候可能会用到:
Things to ignore when debugging an ASP.NET Hang - Update for .NET 2.0
A Hang Scenario, Locks and Critical Sections
作者:Justin
出处:http://justinw.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://justinw.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。