• WinDbg常用命令


    前一篇文章介绍了WinDbg入门,本篇主要介绍WinDbg常用命令和用法。 调试程序的CPU满载问题,关键是要知道程序当前正在进行什么操作。假如我们在cpu满载时创建了一个dump文件,使用下面几个命令可以查看当前程序正在进行什么处理:

    .time

    运行.time命令会显示时间相关的信息,如系统运行时间,进程运行时间和CPU花费在内核态和用户态的时间。

    0:000> .time
    Debug session time: Tue Oct 23 08:38:35.000 2007 (GMT+1)
    System Uptime: 4 days 17:48:01.906
    Process Uptime: 0 days 0:24:37.000
      Kernel time: 0 days 0:04:23.000
      User time: 0 days 0:03:28.000

    你可以看到系统已正常运行超过4天,进程运行了24分钟,CPU在内核态和用户态累积使用了8分钟。根据进程时间和CPU时间能大概估算出CPU使用率平均值是32.5%。

    !threadpool

    通过!threadpool命令我们能准确知道创建dump时cpu的使用率。也能知道在队列中的待处理请求数,Completion Port(IOCP)线程数和定时器time数。

    0:000> !threadpool
    CPU utilization 100%
    Worker Thread: Total: 5 Running: 4 Idle: 1 MaxLimit: 200 MinLimit: 2
    Work Request in Queue: 16
    Unknown Function: 6a2d945d  Context: 023ede30
    Unknown Function: 6a2d945d  Context: 023ee1e8
    AsyncTimerCallbackCompletion TimerInfo@11b53760
    Unknown Function: 6a2d945d  Context: 023ee3a8
    Unknown Function: 6a2d945d  Context: 023e3040
    Unknown Function: 6a2d945d  Context: 023ee178
    Unknown Function: 6a2d945d  Context: 023edfb0
    AsyncTimerCallbackCompletion TimerInfo@11b36428
    AsyncTimerCallbackCompletion TimerInfo@11b53868
    Unknown Function: 6a2d945d  Context: 023ee060
    Unknown Function: 6a2d945d  Context: 023ee290
    Unknown Function: 6a2d945d  Context: 023eded0
    Unknown Function: 6a2d945d  Context: 023edd88
    Unknown Function: 6a2d945d  Context: 023ede98
    Unknown Function: 6a2d945d  Context: 023ee258
    Unknown Function: 6a2d945d  Context: 023edfe8
    --------------------------------------
    Number of Timers: 9
    --------------------------------------
    Completion Port Thread:Total: 3 Free: 3 MaxFree: 4 CurrentLimit: 2 MaxLimit: 200 MinLimit: 2

    我们可以看到当前CPU已100%使用率,我们进入下一命令。

    !runaway

    这个命令用于显示所有正在运行的线程和它们的CPU使用率。这个命令对于查找高CPU使用率问题很有帮助!

    0:000> !runaway
    User Mode Time
      Thread       Time
      25:1a94      0 days 0:00:39.937
      16:1bc0      0 days 0:00:38.390
      50:1e8c      0 days 0:00:08.859
      52:1e40      0 days 0:00:08.687
      20:1c2c      0 days 0:00:08.234
      51:1340      0 days 0:00:08.171
      21:1bcc      0 days 0:00:06.953
      26:13ec      0 days 0:00:06.671
      44:131c      0 days 0:00:03.906
      22:d8c       0 days 0:00:03.375
      33:78c       0 days 0:00:02.656
      34:1a8c      0 days 0:00:00.906
      29:1f5c      0 days 0:00:00.828
       6:e28       0 days 0:00:00.625
       5:1c78      0 days 0:00:00.546
      23:14a4      0 days 0:00:00.484
       4:5ac       0 days 0:00:00.437
      45:5dc       0 days 0:00:00.421
       3:13b4      0 days 0:00:00.421
      47:19c8      0 days 0:00:00.375
      28:1b6c      0 days 0:00:00.250
      46:1dac      0 days 0:00:00.156
       7:1dd8      0 days 0:00:00.109
      48:cdc       0 days 0:00:00.093
      49:1eac      0 days 0:00:00.062
      15:1a64      0 days 0:00:00.062
       0:1804      0 days 0:00:00.046
      36:4a4       0 days 0:00:00.031
      11:1eb4      0 days 0:00:00.031
       1:10b4      0 days 0:00:00.031
      31:16ac      0 days 0:00:00.015
      14:4ac       0 days 0:00:00.015
       2:186c      0 days 0:00:00.015
      59:590       0 days 0:00:00.000
      58:294       0 days 0:00:00.000
      57:16d0      0 days 0:00:00.000
      56:1578      0 days 0:00:00.000
      55:1428      0 days 0:00:00.000
      54:16d8      0 days 0:00:00.000
      53:fd8       0 days 0:00:00.000
      43:1b8c      0 days 0:00:00.000
      42:1c24      0 days 0:00:00.000
      41:1e2c      0 days 0:00:00.000
      40:11b0      0 days 0:00:00.000
      39:edc       0 days 0:00:00.000
      38:1a08      0 days 0:00:00.000
      37:171c      0 days 0:00:00.000
      35:1254      0 days 0:00:00.000
      32:1f9c      0 days 0:00:00.000
      30:1ae8      0 days 0:00:00.000
      27:190c      0 days 0:00:00.000
      24:1d2c      0 days 0:00:00.000
      19:1e38      0 days 0:00:00.000
      18:ee4       0 days 0:00:00.000
      17:fb8       0 days 0:00:00.000
      13:1b54      0 days 0:00:00.000
      12:1a48      0 days 0:00:00.000
      10:f64       0 days 0:00:00.000
       9:1024      0 days 0:00:00.000
       8:1b78      0 days 0:00:00.000

    你可以看到运行线程的总时间和使用.time命令看到的总cpu使用时间并不相等。原因很简单,因为线程被重复使用或回收了。这也意味着一个线程的CPU使用时间可能是处理多个请求的结果。

    !threads

    !threads显示当前所有的托管线程信息。输出如下:

    0:000> !threads
    ThreadCount: 48
    UnstartedThread: 0
    BackgroundThread: 29
    PendingThread: 0
    DeadThread: 19
    Hosted Runtime: no
                                          PreEmptive   GC Alloc           Lock
      ID    OSID ThreadOBJ    State     GC       Context         Domain   Count APT Exception
      16    1 1bc0 001fccd0   1808220 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
      22    2  d8c 002016f0      b220 Enabled  00000000:00000000 0019daf0     0 MTA (Finalizer)
      14    4  4ac 00242e58   880a220 Enabled  00000000:00000000 0019daf0     0 MTA (Threadpool Completion Port)
      23    5 14a4 11b39f18    80a220 Enabled  00000000:00000000 0019daf0     0 MTA (Threadpool Completion Port)
      24    6 1d2c 11b41ad8      1220 Enabled  00000000:00000000 0019daf0     0 Ukn
      25    7 1a94 11b46c70   180b220 Enabled  27240c98:27241fd8 11b42540     1 MTA (Threadpool Worker)
      26    9 13ec 12ce2888   200b220 Enabled  2a9f1434:2a9f33c0 11b42540     0 MTA
      27    a 190c 12d85eb8   200b220 Enabled  00000000:00000000 11b42540     0 MTA
      29    b 1f5c 13df6a50   200b220 Enabled  2ab1da6c:2ab1f1c0 11b42540     0 MTA
      30    c 1ae8 12d44a58      b220 Enabled  00000000:00000000 11b42540     0 MTA
      31    d 16ac 12e2e008   200b220 Enabled  2a81348c:2a8153c0 11b42540     1 MTA
       5    e 1c78 12da2160       220 Enabled  00000000:00000000 0019daf0     0 Ukn
      33    8  78c 11b674c8   200b220 Enabled  2707b818:2707c1d8 11b42540     0 MTA
      34   12 1a8c 13f163c8       220 Enabled  00000000:00000000 0019daf0     0 Ukn
      36   13  4a4 13eef718   200b220 Enabled  2a7db4a4:2a7dd3c0 11b42540     0 MTA
       4   14  5ac 13ef2008       220 Enabled  00000000:00000000 0019daf0     0 Ukn
      42   10 1c24 13f0e950   880b220 Enabled  00000000:00000000 0019daf0     0 MTA (Threadpool Completion Port)
       6   11  e28 13f16008       220 Enabled  00000000:00000000 0019daf0     0 Ukn
       3    f 13b4 13eba008       220 Enabled  00000000:00000000 0019daf0     0 Ukn
      43   15 1b8c 140db008   880b220 Enabled  00000000:00000000 0019daf0     0 MTA (Threadpool Completion Port)
      44   17 131c 140ceb28   200b220 Enabled  272288c8:27229fd8 11b42540     0 MTA
      45   1d  5dc 140cd0a0       220 Enabled  00000000:00000000 0019daf0     0 Ukn
      47   20 19c8 1651a008       220 Enabled  00000000:00000000 0019daf0     0 Ukn
    XXXX   24    0 16468880   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
      46   1f 1dac 1650ab48       220 Enabled  00000000:00000000 0019daf0     0 Ukn
    XXXX   1a    0 140d5008   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
    XXXX   16    0 140c5008   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
      50    3 1e8c 14064420   180b220 Enabled  27246f54:27247fd8 11b42540     1 MTA (Threadpool Worker)
    XXXX   35    0 1406e800   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
      51   36 1340 140df008   180b220 Enabled  2adec9cc:2aded1c0 11b42540     1 MTA (Threadpool Worker)
    XXXX   37    0 16566868   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
      48   38  cdc 16578840       220 Enabled  00000000:00000000 0019daf0     0 Ukn
    XXXX   39    0 16566c28   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
    XXXX   3b    0 1646b8b0   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
    XXXX   3c    0 16674008   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
    XXXX   3d    0 16676418   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
    XXXX   3e    0 16676fb8   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
    XXXX   3f    0 16674d48   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
    XXXX   40    0 1667de10   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
    XXXX   41    0 16680050   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
    XXXX   42    0 166812e8   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
    XXXX   43    0 16683e60   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
      52   44 1e40 165259e8   180b220 Enabled  2adf126c:2adf31c0 11b42540     1 MTA (Threadpool Worker)
    XXXX   45    0 165b7c08   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
    XXXX   46    0 165aa3d8   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
    XXXX   47    0 165242c8   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
    XXXX   48    0 165e9500   1801820 Enabled  00000000:00000000 0019daf0     0 Ukn (Threadpool Worker)
      49   3a 1eac 165676f0       220 Enabled  00000000:00000000 0019daf0     0 Ukn

    线程ID为XXXX表示该线程已结束,并在等待回收。我们也能看到线程ID为22的线程正在终结(finalizer)。假如我们使用!runaway命令时看到22线程有大量的cpu活动,可能我们的程序有终结(finalizer)问题。

    切换到指定线程

    要切换到指定的线程,可以使用下面的格式命令:~[thread id]s,假如我们要切换到50线程,命令如下:

    0:000> ~50s

    现在我们已切换到线程50,可以使用很多其他有用的命令。

    !clrstack

    !clrstack显示当前线程的堆栈信息,通过指定“-p”参数,还能看到方法调用的参数和局部变量信息。 下面是线程50的堆栈信息:

    0:050> !clrstack
    OS Thread Id: 0x1e8c (50)
    ESP       EIP     
    17a9e750 7d61c828 [NDirectMethodFrameSlim: 17a9e750] System.DirectoryServices.Protocols.Wldap32.ldap_bind_s(IntPtr, System.String, System.DirectoryServices.Protocols.SEC_WINNT_AUTH_IDENTITY_EX, System.DirectoryServices.Protocols.BindMethod)
    17a9e768 14df70f9 System.DirectoryServices.Protocols.LdapConnection.BindHelper(System.Net.NetworkCredential, Boolean)
    17a9e794 14df6de0 System.DirectoryServices.Protocols.LdapConnection.Bind()
    17a9e79c 14df59e9 System.DirectoryServices.Protocols.LdapConnection.SendRequestHelper(System.DirectoryServices.Protocols.DirectoryRequest, Int32 ByRef)
    17a9e8b8 14df56e8 System.DirectoryServices.Protocols.LdapConnection.SendRequest(System.DirectoryServices.Protocols.DirectoryRequest, System.TimeSpan)
    17a9e8bc 14df5657 [InlinedCallFrame: 17a9e8bc]

    从下向上看,我们能知道LdapConnection调用了SendRequest方法,而SendRequest又调用了SendRequestHelper方法等等。 如果我们执行“!clrstack -p”命令,我们得到信息:

    0:050> !clrstack -p
    OS Thread Id: 0x1e8c (50)
    ESP       EIP     
    17a9e750 7d61c828 [NDirectMethodFrameSlim: 17a9e750] System.DirectoryServices.Protocols.Wldap32.ldap_bind_s(IntPtr, System.String, System.DirectoryServices.Protocols.SEC_WINNT_AUTH_IDENTITY_EX, System.DirectoryServices.Protocols.BindMethod)
    17a9e768 14df70f9 System.DirectoryServices.Protocols.LdapConnection.BindHelper(System.Net.NetworkCredential, Boolean)
        PARAMETERS:
            this = 0x271fdfe0
            newCredential = 
            needSetCredential = 
    
    17a9e794 14df6de0 System.DirectoryServices.Protocols.LdapConnection.Bind()
        PARAMETERS:
            this = 
    
    17a9e79c 14df59e9 System.DirectoryServices.Protocols.LdapConnection.SendRequestHelper(System.DirectoryServices.Protocols.DirectoryRequest, Int32 ByRef)
        PARAMETERS:
            this = 0x271fdfe0
            request = 0x27246e38
            messageID = 0x17a9e8ec
    
    17a9e8b8 14df56e8 System.DirectoryServices.Protocols.LdapConnection.SendRequest(System.DirectoryServices.Protocols.DirectoryRequest, System.TimeSpan)
        PARAMETERS:
            this = 0x271fdfe0
            request = 0x27246e38
            requestTimeout = 
    
    17a9e8bc 14df5657 [InlinedCallFrame: 17a9e8bc]

    我们可以看到DirectoryRequest参数传递给了SendRequest和SendRequestHelper,要查看DirectoryRequest的相关信息,我们只需复制它的地址(0x27246e38),并在下个命令中使用。

    !dumpobject (!do)

    这是另外一个重要的命令。Dumpobject会打印出指定地址的对象的相关信息。我们使用刚才的地址试下:

    0:050> !do 0x27246e38
    Name: System.DirectoryServices.Protocols.SearchRequest
    MethodTable: 14b394c4
    EEClass: 14d97ce0
    Size: 52(0x34) bytes
    GC Generation: 0
    (C:\WINDOWS\assembly\GAC_MSIL\System.DirectoryServices.Protocols\2.0.0.0__b03f5f7f11d50a3a\System.DirectoryServices.Protocols.dll)
    Fields:
          MT    Field   Offset                 Type VT     Attr    Value Name
    02c39310  4000102        4        System.String  0 instance 00000000 directoryRequestID
    14b398bc  4000103        8 ...ControlCollection  0 instance 27246e90 directoryControlCollection
    02c39310  4000111        c        System.String  0 instance 27246d00 dn
    12579f5c  4000112       10 ....StringCollection  0 instance 27246eb4 directoryAttributes
    02c36ca0  4000113       14        System.Object  0 instance 27246ddc directoryFilter
    14b39344  4000114       18         System.Int32  1 instance        1 directoryScope
    14b393fc  4000115       1c         System.Int32  1 instance        0 directoryRefAlias
    0fd3da00  4000116       20         System.Int32  1 instance        0 directorySizeLimit
    1202af88  4000117       28      System.TimeSpan  1 instance 27246e60 directoryTimeLimit
    120261c8  4000118       24       System.Boolean  1 instance        0 directoryTypesOnly

    通过打印的信息,可以知道它是System.DirectoryServices.Protocols.SearchRequest的一个对象,而显示的都是 System.DirectoryServices.Protocols.SearchRequest的属性值。要知道SearchRequest类的相关属性信息,可以查看MSDN。当前我们已有RequestId, Scope和DistinguishedName等等。 所以,假如我们想知道SearchRequest对象的DistinguishedName属性值,即是上面列表中的dn,我们只需再复制它的地址(27246d00),并再次使用!dumpobject命令。因为DistinguishedName是System.String类型,所以输出结果很明显:

    0:050> !do 27246d00 
    Name: System.String
    MethodTable: 02c39310
    EEClass: 0fb610ac
    Size: 112(0x70) bytes
    GC Generation: 0
    (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
    String: CN=Dummy,CN=Accounts,CN=useradm,DC=dummy,DC=net
    Fields:
          MT    Field   Offset                 Type VT     Attr    Value Name
    0fd3da00  4000096        4         System.Int32  1 instance       48 m_arrayLength
    0fd3da00  4000097        8         System.Int32  1 instance       47 m_stringLength
    0fb80010  4000098        c          System.Char  1 instance       43 m_firstChar
    02c39310  4000099       10        System.String  0   shared   static Empty
        >> Domain:Value  0019daf0:03380310 11b42540:03380310 << 0fb86d44  400009a       14        System.Char[]  0   shared   static WhitespaceChars     >> Domain:Value  0019daf0:03380324 11b42540:033855bc <<

    通过输出的信息我们很容易知道DistinguishedName属性的值是“CN=Dummy,CN=Accounts,CN=useradm,DC=dummy,DC=net”。如果我们想查看更多内容,只需继续使用!dumpobject命令即可。

    !dumpstackobjects (!dso)

    使用该命令我们可以查看到当前线程的堆栈引用的所有托管对象。打印信息如下:

    0:050> !dso
    OS Thread Id: 0x1e8c (50)
    ESP/REG  Object   Name
    17a9e534 0741f860 System.RuntimeType
    17a9e6b8 271fdfe0 System.DirectoryServices.Protocols.LdapConnection
    17a9e6bc 27246f20 System.DirectoryServices.Protocols.SEC_WINNT_AUTH_IDENTITY_EX
    17a9e740 271fdfe0 System.DirectoryServices.Protocols.LdapConnection
    17a9e744 27246f20 System.DirectoryServices.Protocols.SEC_WINNT_AUTH_IDENTITY_EX
    17a9e764 27246f20 System.DirectoryServices.Protocols.SEC_WINNT_AUTH_IDENTITY_EX
    17a9e768 271fdfe0 System.DirectoryServices.Protocols.LdapConnection
    17a9e780 271fdfe0 System.DirectoryServices.Protocols.LdapConnection
    17a9e784 27246e38 System.DirectoryServices.Protocols.SearchRequest
    17a9e794 271fdf14 System.DirectoryServices.Protocols.LdapDirectoryIdentifier
    17a9e7a8 27246ef8 System.Collections.ArrayList
    17a9e7bc 27246ef8 System.Collections.ArrayList
    17a9e7c8 271fdfe0 System.DirectoryServices.Protocols.LdapConnection
    17a9e8a4 27246e38 System.DirectoryServices.Protocols.SearchRequest
    17a9e8d0 27246ed8 System.Object[]    (System.Object[])
    17a9e8e0 073ff6b8 System.String    cn
    17a9e8e4 271fdfe0 System.DirectoryServices.Protocols.LdapConnection
    17a9e8f4 27246d00 System.String    CN=Dummy,CN=Accounts,CN=useradm,DC=Dummy,DC=net
    17a9e8f8 271fdfe0 System.DirectoryServices.Protocols.LdapConnection
    17a9e8fc 27246e38 System.DirectoryServices.Protocols.SearchRequest
    17a9e910 03380310 System.String    
    17a9e914 27246e24 System.Object[]    (System.String[])
    17a9e918 272399a8 System.String    CN=OID-Dummy-ABC123,CN=Dummy,CN=Accounts,CN=useradm,DC=Dummy,DC=net
    17a9e91c 27246ddc System.String    (CN=OID-Dummy-ABC123)
    ...etc...
    
    

    这个命令对于查找当前线程引用了那些对象很有用。假如你想查看某一对象,只需复制[Object]字段的地址,并使用 !dumpobject命令:

    0:050> !do 271fdfe0 
    Name: System.DirectoryServices.Protocols.LdapConnection
    MethodTable: 14a2040c
    EEClass: 149daf08
    Size: 56(0x38) bytes
    (C:\WINDOWS\assembly\GAC_MSIL\System.DirectoryServices.Protocols\2.0.0.0__b03f5f7f11d50a3a\System.DirectoryServices.Protocols.dll)
    Fields:
          MT    Field   Offset                 Type VT     Attr    Value Name
    14a2078c  40000c3        4 ...NetworkCredential  0 instance 00000000 directoryCredential
    14a2144c  40000c4        8 ...ificateCollection  0 instance 271fe018 certificatesCollection
    1202af88  40000c5       10      System.TimeSpan  1 instance 271fdff0 connectionTimeOut
    1466fe50  40000c6        c ...rectoryIdentifier  0 instance 271fdf14 directoryIdentifier
    14a2034c  4000236       24         System.Int32  0 instance        2 connectionAuthType
    14a223a4  4000237       18 ...dapSessionOptions  0 instance 271fe2d8 options
    0fb896d8  4000238       28        System.IntPtr  0 instance 564180944 ldapHandle
    120261c8  4000239       2c       System.Boolean  0 instance        0 disposed
    120261c8  400023a       2d       System.Boolean  0 instance        0 bounded
    120261c8  400023b       2e       System.Boolean  0 instance        0 needRebind
    14a22084  400023e       1c ...pResponseCallback  0 instance 271fe03c fd
    120261c8  4000243       2f       System.Boolean  0 instance        0 setFQDNDone
    120261c8  4000244       30       System.Boolean  0 instance        1 automaticBind
    120261c8  4000245       31       System.Boolean  0 instance        1 needDispose
    120261c8  4000246       32       System.Boolean  0 instance        1 connected
    14a2267c  4000247       20 ...s.QUERYCLIENTCERT  0 instance 271fe394 clientCertificateRoutine
    0fd314bc  400023c       20 ...ections.Hashtable  0   shared   static handleTable
        >> Domain:Value  0019daf0:NotInit  11b42540:073fe504 < <
    02c36ca0  400023d       24        System.Object  0   shared   static objectLock
        >> Domain:Value  0019daf0:NotInit  11b42540:073fe53c < <
    0fd314bc  400023f       28 ...ections.Hashtable  0   shared   static asyncResultTable
        >> Domain:Value  0019daf0:NotInit  11b42540:073fe610 < <
    14a21864  4000240       2c ...lResultsProcessor  0   shared   static partialResultsProcessor
        >> Domain:Value  0019daf0:NotInit  11b42540:073fe678 < <
    12305e94  4000241       30 ....ManualResetEvent  0   shared   static waitHandle
        >> Domain:Value  0019daf0:NotInit  11b42540:073fe64c < <
    14a21954  4000242       34 ...lResultsRetriever  0   shared   static retriever
        >> Domain:Value  0019daf0:NotInit  11b42540:073fe6a8 < <
    

    !dumparray (!da)

    你可能已经注意到有很多对象数组在堆栈中,在上面的列表中查找System.Object[]类型就能找到。如果你对对象数组使用 !dumpobject命令,你只能看到数组信息,而不能看到数组的内容信息,要看到数组内容信息,就需要使用!dumparray命令,或简称!da:

    0:050> !do 27239b98 
    Name: System.Object[]
    MethodTable: 02c3896c
    EEClass: 02c388ec
    Size: 24(0x18) bytes
    Array: Rank 1, Number of elements 2, Type CLASS
    Element Type: System.String
    Fields:
    None
    
    0:050> !da 27239b98 
    Name: System.String[]
    MethodTable: 02c3896c
    EEClass: 02c388ec
    Size: 24(0x18) bytes
    Array: Rank 1, Number of elements 2, Type CLASS
    Element Methodtable: 02c39310
    [0] 272399a8
    [1] 27239a44
    
    

    通过!dumparray命令我们能知道该数组对象是字符串数组,并给出了数组项的地址。再使用!dumpobject命令我们就能看到数组项的具体内容。 !objsize 如果你查看上面打印的信息,可以看到对象的大小是24字节。从某方面来说,这是对的,24字节是System.Object[]数组对象本身大小,但并不包括数组内容的大小!要获得整个对象的大小,就要使用到 !objsize命令:

    0:050> !objsize 27239b98 
    sizeof(27239b98) =          348 (       0x15c) bytes (System.Object[])
    

    !objsize会遍历对象引用的所有子对象,并计算出总的大小。如上面数组对象和它的内容的总大小是348字节。 如果对象有引用很多子对象,那么!objsize会花费较多的时间计算出总大小。

    !dumpheap

    这是另一个较频繁使用的命令。!dumpheap会打印出所有在托管堆中的对象信息。直接执行该命令会打印出大量的信息,所以一般使用时都至少带上一个参数。加上-stat参数后会输出总结后的信息,如下面是截取的是!dumpheap -stat命令输出的一部分:

    0:050> !dumpheap -stat
    ------------------------------
    Heap 0
    total 2754508 objects
    ------------------------------
    Heap 1
    total 2761329 objects
    ------------------------------
    total 5515837 objects
    Statistics:
          MT    Count    TotalSize Class Name
    16e0a6d8        1           12 System.Collections.Generic.ObjectEqualityComparer`1[[System.Data.ProviderBase.DbConnectionInternal, System.Data]]
    16d9cd9c        1           12 System.Xml.Serialization.Configuration.DateTimeSerializationSection+DateTimeSerializationMode
    16d9bf30        1           12 System.Diagnostics.OrdinalCaseInsensitiveComparer
    16d9112c        1           12 System.Xml.Serialization.NameTable
    16d7f664        1           12 System.Xml.Serialization.TempAssemblyCache
    163ea85c        1           12 System.Data.Res
    1501e4c4        1           12 System.Collections.Generic.ObjectEqualityComparer`1[[System.Web.UI.Control, System.Web]]
    14efb138        1           12 System.Net.TimeoutValidator
    14ef9964        1           12 System.Net.Cache.HttpRequestCacheLevel
    14ef77a8        1           12 Microsoft.Win32.WinInetCache
    14ef68e4        1           12 System.Net.WebRequest+WebProxyWrapper
    14ef658c        1           12 System.Net.Configuration.ProxyElement+BypassOnLocalValues
    14ef63d8        1           12 System.Net.Configuration.ProxyElement+AutoDetectValues
    14ef5b68        1           12 System.Net.CaseInsensitiveAscii
    14ef5610        1           12 System.Net.HeaderInfoTable
    14ef4718        1           12 System.Net.HttpRequestCreator
    14db6710        1           12 System.Web.Configuration.MachineKeyValidationConverter
    14db3140        1           12 System.Collections.Generic.ObjectEqualityComparer`1[[System.Runtime.Serialization.MemberHolder, mscorlib]]
    14b3f4d8        1           12 System.Web.UI.SupportsEventValidationAttribute
    ...etc...
    14a276a8    19578       704808 System.DirectoryServices.Interop.AdsValueHelper
    14a2ea24     9196       735680 System.Web.UI.WebControls.Label
    14a2e51c    16862       741928 System.Web.UI.WebControls.Style
    125778ec    48015       768240 System.Collections.Specialized.NameObjectCollectionBase+NameObjectEntry
    120261c8    65842       790104 System.Boolean
    14a2ee7c     9198       809424 System.Web.UI.WebControls.Table
    14b311c4     9647       810348 System.Web.UI.WebControls.Image
    13a2b7dc    34913       837912 System.Web.HttpServerVarsCollectionEntry
    14b303a4    10605       848400 System.Web.UI.WebControls.HyperLink
    14d8e3d4    77748       932976 Microsoft.Web.UI.WebControls.BaseChildNodeCollection+ActionType
    14db90ac    81372       976464 System.Web.UI.WebControls.FontInfo
    14b30694    28648      1031328 System.Web.UI.WebControls.TableRow+CellControlCollection
    14d8fdbc    38912      1089536 Microsoft.Web.UI.WebControls.TreeNodeCollection
    14b3d0bc    86592      1385472 System.Web.UI.Pair
    1466c5c4    39305      1414980 System.Web.UI.ControlCollection
    14d8e48c    77748      1865952 Microsoft.Web.UI.WebControls.BaseChildNodeCollection+Action
    1545061c    38874      2176944 Microsoft.Web.UI.WebControls.TreeNode
    14b30eec    52668      2317392 System.Web.UI.WebControls.TableItemStyle
    14a2f804    28515      2395260 System.Web.UI.WebControls.TableRow
    14a2be6c    40894      2453640 System.Web.UI.LiteralControl
    0fd3da00   228792      2745504 System.Int32
    14b3e3ac   244793      2937516 System.Web.UI.IndexedString
    14a2de94   198580      3177280 System.Web.UI.StateBag
    1466c454    80512      3542528 System.Web.UI.Control+OccasionalFields
    12302c2c   205849      4116980 System.Collections.Specialized.HybridDictionary
    14b30024    52934      4446456 System.Web.UI.WebControls.TableCell
    12302f2c   178294      4992232 System.Collections.Specialized.ListDictionary
    14a2e284   412762      6604192 System.Web.UI.StateItem
    14d8ce64   117078      7024680 Microsoft.Web.UI.WebControls.CssCollection
    0fd314bc   132065      7395640 System.Collections.Hashtable
    1230319c   422580      8451600 System.Collections.Specialized.ListDictionary+DictionaryNode
    1202a58c   380438      9130512 System.Collections.ArrayList
    0fd32050   133000     22582944 System.Collections.Hashtable+bucket[]
    02c3896c   649842     23275900 System.Object[]
    0fd3c12c     3471     36385536 System.Byte[]
    001fee20      338     65409920      Free
    02c39310   683083    161821000 System.String
    Total 5515837 objects
    Fragmented blocks larger than 0.5 MB:
        Addr     Size      Followed by
    2adf31cc    2.0MB         2aff85d8 System.String
    2b006a2c   20.3MB         2c4530d8 System.Net.SocketAddress
    
    

    输出信息按对象类型的总大小升序排序,你一般可以在列表的最下面找到string对象的大小,因为字符串在程序中一般是最常用的。 其他比较有用的参数是-type和-mt(MethodTable的意思)。使用它们你可以查看指定对象类型的详细信息,例如假如我们想查看System.Net.HttpRequestCreator类型的具体信息,可以复制上面列表中它的MT字段地址(14ef4718),然后使用 !dumpheap -mt命令:

    0:050> !dumpheap -mt 14ef4718        
    ------------------------------
    Heap 0
    Address       MT     Size
    0342ccf8 14ef4718       12     
    total 1 objects
    ------------------------------
    Heap 1
    Address       MT     Size
    total 0 objects
    ------------------------------
    total 1 objects
    Statistics:
          MT    Count    TotalSize Class Name
    14ef4718        1           12 System.Net.HttpRequestCreator
    

    上面列出了所有System.Net.HttpRequestCreator类型的对象的地址,假如我们想查看指定对象的信息,再使用!dumpobject命令就可以了。 !dumpheap -type可以根据字符串来匹配对应的对象类型。如我们输入命令“!dumpheap -type System.Web”,是指显示所有类名包含有“System.Web”字符串的对象信息。 其他参数-min和-max是接受表示对象大小的最大值和最小值(单位字节),命令会只列出大于指定值或小于指定值的对象信息。这两个参数对于查找滥用字符串问题很有帮助。

    实战训练

    查明缓存使用的大小

    为了知道在System.Web.Caching.Cache类型中有多少数据,我执行了“ !dumpheap -stat -type System.Web.Caching.Cache”命令。注意,我用了-stat参数,否则我会得到一个包含有System.Web.Caching.CacheKeys和System.Web.Caching.CacheEntrys对象的很长的列表。下面的执行结果:

    0:050> !dumpheap -type System.Web.Caching.Cache -stat
    ------------------------------
    Heap 0
    total 665 objects
    ------------------------------
    Heap 1
    total 1084 objects
    ------------------------------
    total 1749 objects
    Statistics:
          MT    Count    TotalSize Class Name
    123056f8        1           12 System.Web.Caching.CacheKeyComparer
    1230494c        1           12 System.Web.Caching.Cache
    1230500c        1           24 System.Web.Caching.CacheMultiple
    1230514c        1           32 System.Web.Caching.CacheMemoryStats
    123053b4        1           36 System.Web.Caching.CacheMemoryTotalMemoryPressure
    123059bc        2           40 System.Web.Caching.CacheUsage
    12304bdc        1           48 System.Web.Caching.CacheCommon
    123054f4        1           52 System.Web.Caching.CacheMemoryPrivateBytesPressure
    12305874        2           64 System.Web.Caching.CacheExpires
    12304e64        2          200 System.Web.Caching.CacheSingle
    1255b594       85         1360 System.Web.Caching.CacheDependency+DepFileInfo
    123046c4       40         1440 System.Web.Caching.CacheDependency
    123042ec       47         1504 System.Web.Caching.CacheItemRemovedCallback
    123063fc      832        16640 System.Web.Caching.CacheKey
    12306820      732        52704 System.Web.Caching.CacheEntry
    Total 1749 objects
    
    

    很明显System.Web.Caching.Cache的方法列表地址(MethodTable)是1230494c,再使用!dumpheap命令我就能看到它的所有对象信息,如下:

    0:050> !dumpheap -mt 1230494c        
    ------------------------------
    Heap 0
    Address       MT     Size
    03392d20 1230494c       12     
    total 1 objects
    ------------------------------
    Heap 1
    Address       MT     Size
    total 0 objects
    ------------------------------
    total 1 objects
    Statistics:
          MT    Count    TotalSize Class Name
    1230494c        1           12 System.Web.Caching.Cache
    Total 1 objects
    

    可以看到System.Web.Caching.Cache类型只有一个对象,地址是03392d20,再通过!objsize命令就能计算出它的大小。因为缓存对象很复杂,并包含有大量的子对象,要计算出总大小需要花些时间:

    0:050> !objsize 03392d20 
    sizeof(03392d20) =    266640828 (   0xfe49dbc) bytes (System.Web.Caching.Cache)
    

    所以缓存的总大小是 266 MB。

    缓存了什么东西?

    为了弄清缓存中保存了什么内容,我查看了System.Web.Caching.CacheEntry的对象信息。通过之前的信息可以知道System.Web.Caching.CacheEntry类型的方法列表(MethodTable)是12306820。执行!dumpheap命令取CacheEntry的所有对象信息:

    0:050> !dumpheap -mt 12306820      
    ------------------------------
    Heap 0
    Address       MT     Size
    033950bc 12306820       72     
    033a20d8 12306820       72     
    033ac79c 12306820       72     
    033da21c 12306820       72     
    033f04c4 12306820       72     
    03428ec8 12306820       72     
    0344dab4 12306820       72     
    03815d00 12306820       72     
    038265d8 12306820       72     
    ....etc...
    03af7010 12306820       72     
    03b291bc 12306820       72     
    03b2c674 12306820       72     
    03b6dca0 12306820       72     
    03b797dc 12306820       72     
    03b85318 12306820       72     
    03ba9150 12306820       72     
    03c258cc 12306820       72     
    03de43c8 12306820       72     
    03e160f8 12306820       72    
    total 382 objects
    ------------------------------
    total 732 objects
    

    要显示上面的信息,也可以使用“!dumpheap -type System.Web.Caching.CacheEntry”命令。 有了所有CacheEntry对象的地址信息,我随机拿了一个地址查看它的内容:

    0:050> !do 03b2c674 
    Name: System.Web.Caching.CacheEntry
    MethodTable: 12306820
    EEClass: 122f6470
    Size: 72(0x48) bytes
    (C:\WINDOWS\assembly\GAC_32\System.Web\2.0.0.0__b03f5f7f11d50a3a\System.Web.dll)
    Fields:
          MT    Field   Offset                 Type VT     Attr    Value Name
    02c39310  4001327        4        System.String  0 instance 03b2c600 _key
    0fb8f1f8  4001328        c          System.Byte  0 instance        2 _bits
    0fd3da00  4001329        8         System.Int32  0 instance -1314181915 _hashCode
    02c36ca0  4001330       10        System.Object  0 instance 03b2c644 _value
    120219d0  4001331       1c      System.DateTime  1 instance 03b2c690 _utcCreated
    120219d0  4001332       24      System.DateTime  1 instance 03b2c698 _utcExpires
    1202af88  4001333       2c      System.TimeSpan  1 instance 03b2c6a0 _slidingExpiration
    0fb8f1f8  4001334        d          System.Byte  0 instance        7 _expiresBucket
    123062d8  4001335       34 ...g.ExpiresEntryRef  1 instance 03b2c6a8 _expiresEntryRef
    0fb8f1f8  4001336        e          System.Byte  0 instance 4294967295 _usageBucket
    12306738  4001337       38 ...ing.UsageEntryRef  1 instance 03b2c6ac _usageEntryRef
    120219d0  4001338       3c      System.DateTime  1 instance 03b2c6b0 _utcLastUpdate
    123046c4  4001339       14 ...g.CacheDependency  0 instance 00000000 _dependency
    02c36ca0  400133a       18        System.Object  0 instance 033d8344 _onRemovedTargets
    120219d0  400132d      1bc      System.DateTime  1   shared   static NoAbsoluteExpiration
        >> Domain:Value  0019daf0:NotInit  11b42540:03395104 < <
    1202af88  400132e      1c0      System.TimeSpan  1   shared   static NoSlidingExpiration
        >> Domain:Value  0019daf0:NotInit  11b42540:03395114 < <
    1202af88  400132f      1c4      System.TimeSpan  1   shared   static OneYear
        >> Domain:Value  0019daf0:NotInit  11b42540:03395124 < <
    

    输出的是CacheEntry的属性信息,里面最重要的是_value属性。我复制它的地址(03b2c644),再用!dumpobject命令查看:

    0:000> !do 03e160c8 
    Name: System.Web.SessionState.InProcSessionState
    MethodTable: 14dbad5c
    EEClass: 14e43af8
    Size: 48(0x30) bytes
    (C:\WINDOWS\assembly\GAC_32\System.Web\2.0.0.0__b03f5f7f11d50a3a\System.Web.dll)
    Fields:
          MT    Field   Offset                 Type VT     Attr    Value Name
    1466c9d8  4001d89        4 ...ateItemCollection  0 instance 1a7f5438 _sessionItems
    1292672c  4001d8a        8 ...ObjectsCollection  0 instance 00000000 _staticObjects
    0fd3da00  4001d8b        c         System.Int32  0 instance       20 _timeout
    120261c8  4001d8c       18       System.Boolean  0 instance        0 _locked
    120219d0  4001d8d       1c      System.DateTime  1 instance 03e160e4 _utcLockDate
    0fd3da00  4001d8e       10         System.Int32  0 instance        1 _lockCookie
    1202bf60  4001d8f       24 ...ReadWriteSpinLock  1 instance 03e160ec _spinLock
    0fd3da00  4001d90       14         System.Int32  0 instance        0 _flags
    

    可以看到缓存的是一个InProcSessionState对象。

    参考文章: Getting started with windbg - part I Getting started with windbg - part II

  • 相关阅读:
    pm2 配置
    添加项目到远程服务器(git)
    psql 命令行使用
    SQL
    iOS AFNetworking 打印从服务器返回的错误提示信息
    iOS 获取网络图片的大小
    iOS 10 常见配置的问题
    LGLTagsView
    xcode8 关闭控制台打印不用信息
    LGLProgressHUD
  • 原文地址:https://www.cnblogs.com/vento/p/2858150.html
Copyright © 2020-2023  润新知