[Debug实践]用windbg看看线程都在等什么?帮助发现配置错误

时间:2024-02-25 11:58:22

公司的开发环境\测试环境和生产环境的区别都比较大.每次新版本启动前,都需要很长的时间来调试测试环境,很大一部分工作都在于改数据库链接,接口地址.然而看似简单的活却总是存在问题。上周五配置完环境出现了一个现象:cpu和内存的使用都很低,但网页却要很长的时间才能显示,根据以往的经验判断是某个接口地址估计又配错了,引起长时间的等待。但排查了一些最常用的地址后,相关的开发人员都找不出问题的根源。

即然dump文件可以记录活动的线程情况,应该可以用来发现等待点。以下是具体的分析过程,也许这是一个代价过高的方法,希望有更好方法的朋友分享一下。
(1)访问一下测试环境的网站,这时页面在进行长时间的等待,运行adplus.vbs -hang -pn w3wp.exe -o d:\ops\产生一个dump文件

(2)windbg打开产生的dmp文件,先用.load sos.dll加载sos扩展,运行~* e!clrstack查看所有线程的托管堆栈,得到的结果如下:

(3)从上图可以看到,有个线程在等待loadUrlFile方法返回,看看参数值是什么.运行~21 s切换到等待的线程上,运行!clrstack -a
省略一堆的输出,从里头后到如下内容:
0e93ee04 7a5ad0a9 System.Net.Connection.SubmitRequest(System.Net.HttpWebRequest)
    PARAMETERS:
        this = 0x06c97120
        request = 0x06c96844
    LOCALS:
        0x0e93ee1c = 0x00000001
        0x0e93ee18 = 0x00000000
        <no data>
        <no data>
        <no data>
        <no data>
        <no data>
        <no data>

(4)SubmitRequest的request参数应该就是请求的文件地址.!do 0x06c96844,看到request包含如下内容:
7a757bf0  4001f22       5c           System.Uri  0 instance 06c967d0 _Uri
7a757bf0  4001f23       60           System.Uri  0 instance 06c967d0 _OriginUri
790fd8c4  4001f24       64        System.String  0 instance 00000000 _MediaType
790ffcc8  4001f25       1c         System.Int64  1 instance -1 _ContentLength
7a78e938  4001f26       68 System.Net.IWebProxy  0 instance 06867e10 _Proxy
7a794fe8  4001f27       6c ...em.Net.ProxyChain  0 instance 06c96ddc _ProxyChain
790fd8c4  4001f28       70        System.String  0 instance 00000000 _ConnectionGroupName

运行!do 06c967d0 看看uri的值:

0:021> !do 06c967d0
Name: System.Uri
MethodTable: 7a757bf0
EEClass: 7a757a3c
Size: 40(0x28) bytes
 (C:\WINDOWS\assembly\GAC_MSIL\System\2.0.0.0__b77a5c561934e089\System.dll)
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
790fd8c4  4001b51        c        System.String  0 instance 06c96728 m_String

封装得还真是多,汗一个,继续!do 06c96728

(5)看来程序是在等待bbs***/api/***.ph 地址返回,原来是网页上用到了一个取用户评分的接口,测试环境的接口配置到了一台已并闭的论坛服务器上,经修改后一切正常