• Windbg使用简明指南


    第一章 准备

    1.1.    环境配置

    _NT_DEBUGGER_EXTENSION_PATH=C:WINDOWSMicrosoft.NETFrameworkv2.0.50727

    _NT_SYMBOL_PATH=SRV*c:Symbols*http://msdl.microsoft.com/download/symbols

    Path add:

    C:WINDOWSMicrosoft.NETFrameworkv2.0.50727

    C:Program FilesDebugging Tools for Windows (x86)

    1.2 .Net CLR知识

                           

    第二章 常用命令

    2.1 基本命令

    序号

    命令

    解释

    1.    

    .chain

    显示有哪些调试扩展。

    1.    

    .load DLLName

    !DLLName.load

    加载调试扩展。DLLName要是全路径名,包括”.dll”

    1.    

    .loadby DLLName ModuleName

    加载调试扩展。DLLName是短文件名,不包括”.dll”。

    ModuleName是调试进程中的模块名,表示通过它所在的路径查找DLLName。

    1.    

    .unload DLLName

    !DLLName.unload

    卸载调试扩展。

    1.    

    .setdll DLLName

    !DLLName.setdll

    设置缺省的调试扩展。

    1.    

    ![ext.]address

    显示VM的分配状况

    1.    

    ![sos.]vmmap

    显示VM的分配状况

    1.    

    ![uext.]vadump

    输出虚拟地址映射信息

    1.    

    ![uext.]vprot address

    显示给出的虚拟地址所在内存的映射信息。

    1.  

    .logfle

    检查是否有日志文件

    1.  

    .logopen

    .logappend

    打开日志文件。输出内容多时特别有用!

    一个是新建,另一个是追加。

    1.  

    .logclose

    关闭日志文件

    1.  

    dt

    通过符号输出类型的结构拓扑信息。

    1.  

    ![ntsdexts.]heap 0 0

    察看Win32堆的运行状况。

    使用!heap –stat察看heap的内存使用情况。

    1.  

    ![ext.]dlls

    可以察看进程内的动态链接库的信息。

    1.  

    ![sos.]threads

    可以列出所有的托管线程,并在栈顶给出异常对象的地址。

    1.  

    ![sos.]ip2md addr

    可以将IP地址转换成IL对应的方法名。

    1.  

    ![sos.]BPMD <module name>   <method name>

    ![sos.]BPMD -md <MethodDesc>

    可以在托管代码的指定位置设置断点。

    method name是包含namespace.class.method的全名!

    !bpmd myapp.exe MyApp.Main

    Example for generics:

          Given   the following two classes:

          class   G3<T1, T2, T3>

          {

          ...

          public void F(T1 p1, T2 p2, T3 p3)

          { ... }

          }

          public   class G1<T> {

              // static method

              static public void G<W>(W w)

              { ... }

          }

          One   would issue the following commands to set breapoints on G3.F() and  G1.G():

          !bpmd   myapp.exe G3`3.F

          !bpmd   myapp.exe G1`1.G

    1.  

    ![sos.]Name2EE module_name item_name

    ![sos.]Name2EE module_name!item_name

    查找名称(类型/方法/属性)对应的CLR信息

    Examples:

     !Name2EE    mscorlib.dll System.String.ToString

     !Name2EE *!System.String

    Examples:

    0:018> !name2ee mscorlib.dll   System.IntPtr

    Module: 790c2000 (mscorlib.dll)

    Token: 0x020000c1

    MethodTable: 790fe160

    EEClass: 790fe0d0

    Name: System.IntPtr

    1.  

    ![sos.]dumpclass

    查找EEClass对应的信息

    Examples:

    0:018> !DumpClass 790fe0d0

    Class Name: System.IntPtr

    mdToken: 020000c1   (C:WINDOWSassemblyGAC_32mscorlib2.0.0.0__b77a5c561934e089mscorlib.dll)

    Parent Class: 790f9d24

    Module: 790c2000

    Method Table: 790fe160

    Vtable Slots: 5

    Total Method Slots: 1b

    Class Attributes: 102109 

    NumInstanceFields: 1

    NumStaticFields: 1

            MT    Field   Offset                 Type VT     Attr      Value Name

    79118260  40003e0        4                  PTR  0 instance           m_value

    790fe160  40003e1        96c        System.IntPtr  0     shared   static Zero

          >> Domain:Value    000da220:NotInit  000fde60:0   <<

    1.  

    ![sos.]token2ee

    查找mdToken对应的名称信息。

    Examples:

    0:018> !Token2EE mscorlib.dll 020000c1

    Module: 790c2000 (mscorlib.dll)

    Token: 0x020000c1

    MethodTable: 790fe160

    EEClass: 790fe0d0

    Name: System.IntPtr

    1.  

    c rgBuf1 L 100 rgBuf2

    比较内存

    1.  

    as

    设置别名,例:

    as Name EquivalentLine

    aS Name EquivalentPhrase

    aS Name "EquivalentPhrase"

    as /e Name EnvironmentVariable

    as /ma Name Address

    as /mu Name Address

    as /msa Name Address

    as /msu Name Address

    as /x Name Expression

    aS /f Name File

    as /c Name CommandString

    1.  

    ad

    删除别名,例:

    ad [/q] Name

    ad *

    1.  

    al

    列表别名。例:

    al

    1.  

    ${ }

    解释(提取)别名,例:

    Text ${Alias} Text

    Text ${/d:Alias} Text

    Text ${/f:Alias} Text

    Text ${/n:Alias} Text

    Text ${/v:Alias} Text

    1.  

    特别有用的MASM命令处理函数.

    $fnsucc(FnAddress, RetVal, Flag)

    $iment (Address)

    $scmp("String1",   "String2")

    $sicmp("String1",   "String2")

    $spat("String",   "Pattern")

    $vvalid(Address, Length)

    1.  

    ~#s

    设置当前线程上下文。例:

    0: kd> ~1s

    1: kd>

    1.  

    $<, $><, $$<, $$><, $$>a<

    (Run Script File)

    $<Filename

    $><Filename

    $$< Filename

    $$>< Filename

    $$>a< Filename arg1   arg2 arg3 ... argn

    1.  

    !runaway

    The   !runaway extension displays information about the time consumed by each   thread.

    查看线程信息

    Flags

          Specifies the kind of information to be displayed. Flags can be any   combination of the following bits. The default value is 0x1:

    Bit 0 (0x1)

          Causes the debugger to show the amount of user time consumed by each   thread.

    Bit 1 (0x2)

          Causes the debugger to show the amount of kernel time consumed by each   thread.

    Bit 2 (0x4)

          Causes the debugger to show the amount of time that has elapsed since   each thread was created.

    0:001> !runaway 7

    例:

     User Mode Time

     Thread         Time

     0:55c        0:00:00.0093

     1:1a4        0:00:00.0000

     Kernel Mode Time

     Thread         Time

     0:55c        0:00:00.0140

     1:1a4        0:00:00.0000

     Elapsed Time

     Thread         Time

     0:55c        0:00:43.0533

     1:1a4        0:00:25.0876

    1.  

    !envvar Variable

    获取环境变量的值

    0:000>   !envvar _nt_symbol_path

            _nt_symbol_path =   srv*C:mysyms*http://msdl.microsoft.com/download/symbols

    1.  

    .printf

    类似C库的printf函数,可以接收的参数有:

    %p, %N, %I, %ma, %mu, %msa, %msu, %y, %ly

    除了文档中给出的参数,还可以接收C库中的格式化字符串,如:

    %d, %c, %d, %f, %E等,功能强劲。

    如果需要输出64位数字,可以使用"%I64x"。如:

    0:000> .printf "%I64x",   0x00001234`00000123;

    123400000123

    1.  

    n [Radix]

    Set   Number Base

    命令格式:

        n [Radix]

    Radix  

        Specifies the default number base that is   used for numeric display and entry. You can use one of the following values.

        8      Octal   

        10     Decimal

        16     Hexadecimal

    1.  

    ![sos.]clrstack

    !CLRStack [-a] [-l] [-p]

    -a –l –p选项可以输出栈的参数,非常有用!

    1.  

    ![sos.]DumpStack

    !DumpStack [-EE] [top stack [bottom stack]]

    比ClrStack的输出内容更为详尽,能同时显示native和.NET的堆栈信息!top stack/bottom stack是从k系列命令看到的栈顶和栈底地址。 -EE 限制只输出.NET堆栈。

    如:

    !DumpStack 77b1dae4 77b1dba4

    1.  

    ![exts.]tp

    !tp   pool Address [Flags]

    !tp   tqueue Address [Flags]

    !tp   ItemType Address [Flags]

    !tp   ThreadType [Address]

    !tp   -?

    察看OS的thread pool信息

    1.  

    ![sos.]threadpool

    察看.NET使用的thread pool的统计信息。

    1.  

    x

    x [Options] Module!Symbol

    x [Options] *!*

    检查加载的符号,特别有用!

    注意,Module是模块名,不带.dll。例:

    0:000> x mymodule!*spin*

    0:000> x *!*

    1.  

    j

    j   (Execute If - Else)

    j   Expression Command1 ; Command2

    j   Expression 'Command1' ; 'Command2'

    If   this expression evaluates to a nonzero value, Command1 is executed. If this   expression evaluates to zero, Command2 is executed.例:

    0:000> bp `mysource.cpp:143` "j   (poi(MyVar)>0n20) ''; 'gc' "

    0:000> j (MySymbol=0) 'r eax'; 'r ebx; r ecx'

    0:000> j (MySymbol=0) ''; 'r ebx; r ecx'

    0:000> j (MySymbol=0)  ; 'r ebx; r ecx'

    1.  

    g

    gc

    如果在条件断点之中,应使用gc命令,这样如果通过step或trace进入断点,那么出断点gc维持step或trace命令;而g命令无论怎么进入断点都使用g命令执行。

    0:000>   bp Address "j (Condition) 'OptionalCommands'; 'gc' "

    0:000>   bp Address "j (Condition) 'OptionalCommands'; 'g' "

    1.  

    gu

    The   gu command causes the target to execute until the current function is   complete.

    User-Mode Syntax

    [~Thread] gu

    Kernel-Mode Syntax

    gu  

    1.  

    ![sos.]findappdomain

    !findappdomain <object address>

    查找对象所在的AppDomain

    1.  

    sx, sxd, sxe,   sxi, sxn, sxr

    sx,   sxd, sxe, sxi, sxn, sxr (Set Exceptions)

    设置异常发生后调试器的行为。

    sx

    sx{e|d|i|n} [-c   "Cmd1"] [-c2 "Cmd2"] [-h] {Exception|Event|*}

    sxr

    sx查看系统异常处理列表;

    sxr重置系统异常处理列表;

    sxe  

    Break   (Enabled)  When this exception occurs,   the target immediately breaks into the debugger before any other error   handlers are activated. This kind of handling is called first chance   handling.

    sxd

    Second   chance break (Disabled). The debugger does not break for a first-chance   exception of this type (although a message is displayed). If other error   handlers do not address this exception, execution stops and the target breaks   into the debugger. This kind of handling is called second chance handling.

    sxn

    Output   (Notify). When this exception occurs, the target application does not break   into the debugger at all. However, a message is displayed that notifies the   user of this exception.

    sxi

    Ignore   When this exception occurs, the target application does not break into the   debugger at all, and no message is displayed.

    1.  

    #

    #   (Search for Disassembly Pattern)

    # [Pattern] [Address [ L   Size ]]

    示例:

    #  mov    0040116b

    #  8945*    0040116b

    #  116d    0040116b

    # strlen main

    例如:在反汇编“8b4510          mov     eax,dword ptr [ebp+10h]”查找[ebp+10h],命令如下:

    #   [ebp+10h] 7c810000

    注意,这个命令进行的是形式匹配!因此要求先查看U命令的输出结果。

    1.  

    ld

    ld   (Load Symbols)

    ld   [ModuleName]

    加载调试信息。在对付lazy load的dll时比较有用。

    1.  

    ln

    ln   (List Nearest Symbols)

    ln   Address

    The   ln command displays the symbols at or near the given address.

    1.  

    ls, lsa

    ls,   lsa (List Source Lines)

    ls   [.] [first] [, count]

    lsa   [.] address [, first [, count]]

    1.  

    .context

    .context   (Set User-Mode Address Context)

    .context   [PageDirectoryBase]

    PDB地址来自.process命令

    kd>   !process 0 0

    PROCESS   fe3c0d60  SessionId: 0  Cid: 0208      Peb: 7ffdf000  ParentCid: 00d4

        DirBase: 0011f000  ObjectTable: fe3d0f48    TableSize:  30.

    Image: regsvc.exe

    1.  

    .process

    .process   (Set Process Context)

    The   .process command specifies which process is used for the process context.

    Syntax

    .process   [/i] [/p [/r] ] [/P] [Process]

    1.  

    .thread

    .thread   (Set Register Context)

    The   .thread command specifies which thread will be used for the register context.

    Syntax

    .thread   [/p [/r] ] [/P] [/w] [Thread]

    1.  

    .time

    .time (Display System Time)

    0:000> .time

    Debug session time: Mon Apr 07 19:10:50 2003

    System Uptime: 4 days   4:53:56.461   OS已经运行了多久

    Process Uptime: 0 days   0:00:08.750  进程已经运行了多久

      Kernel time: 0 days   0:00:00.015

      User time: 0 days   0:00:00.015

    1.  

    .ttime

    The   .ttime command displays the running times for a thread.

    0:000>   .ttime

    Created: Sat Jun 28 17:58:42 2003

    Kernel:  0 days 0:00:00.131

    User:    0 days 0:00:02.109

    1.  

    .writemem

    .writemem   FileName Range

    1.  

    ![exts.]peb

    The   !peb extension displays a formatted view of the information in the process   environment block (PEB).

    Syntax

    !peb   [PEB-Address]

    1.  

    ![exts.]teb

    The   !teb extension displays a formatted view of the information in the thread   environment block (TEB).

    Syntax

    !teb   [TEB-Address]

    1.  

    ![exts.]tls

    The   !tls extension displays a thread local storage (TLS) slot.

    Syntax

        !tls Slot [TEB]

    Parameters

    Slot  

    Specifies   the TLS slot. This can be any value between 0 and 1088 (decimal). If Slot is -1, all slots are displayed.

    TEB  

    Specifies   the thread environment block (TEB). If this is 0 or   omitted, the current thread is used.

    1.  

    ![ntsdexts.]locks

    !locks   [-v][-o]              - Dump all Critical   Sections in process

    2.2.    常用命令

    得到dump文件:

    Adplus -hang -pn w3wp.exe -quiet (hang)   [-FullOnFirst]

    adplus -crash -pn w3wp.exe (crash)

    加载 sos 扩展功能dll:

    .load sos.dll

    .loadby sos mscorwks

    自动分析

    !analyze –v

     

    !analyze -hang。这个扩展将会执行一个线程栈分析以确定是不是有哪些线程正在阻塞其他线程。

    查看版本:

    !eeversion

    查看异常:

    !dumpallexceptions

    运行 help 命令:

    !help

    !help [command name]   //查找某个命令更多详细的内容, 如: !help eeversion

    显示系统与时间有关的信息:

    .time

    dump文件时cpu的使用情况。同时可以得到其他的有用的信息(例如:等待请求队列的数量,已完成的线程和时间):

    !threadpool

    列出当前正在运行的线程和cpu使用情况

    !runaway                 //比如查看哪个线程占用 CPU 时间过多

    列表显示出应用程序所有正在运行的线程,当前应用程序域中后台正在运行的程序,等等线程相关内容

    !threads

    切换到特定的线程上查看相关内容

    ~[thread id]s  //例如: ~2s

    列出当前线程中的调用栈信息

    !clrstack     //如果想查看额外的信息,添加 “-p”选项, 如: !clrstack –p

    !clrstack -a

    显示指定地址对象的内容:

    !dumpobj 0xf32fcc              //(!do 为简写)

    继续查看对象的值

    !dumpobj -v 0xf32fcc

    !dumpvc 7910c878  01573774  //mt  value

    查看当前特定线程的堆栈中所有托管对象

    !dumpstackobjects (或 简称!dso )           //next:  !dumpobj 0x1d298ad8

    得到当前线程对象中关于数组对象的详细信息

    !dumparray [address]     (简称!da)         //!do [address]仅得到简单信息

    !da –details [address]  //详细信息

    得到对象的整个大小

    !objsize 071bef70

    !objsize poi(0x61b47d4+0xc)      //Address + Offset

    .foreach (obj {!dumpheap -mt 0x0c2eaeb4 -short}){!objsize ${obj}}   //0x0c2eaeb4: mt

    .foreach(myobj {!dumpheap -short -min 85000}) {!objsize myobj} //所有所有对象中大于85K内容

    dump出所有的托管堆上的对象

    !dumpheap –stat             //使用 –stat 参数来得到托管堆上的摘要信息

    参数–mt (即:MethodTable):

    !dumpheap -mt 793308ec      //next: 进一步查看对象,使用 !dumpobj [object address]即可

    参数–mt:

    !dumpheap –type System      //出许多包含 System 名称的对象

    参数是 –min -max ,该参数接受一个最小最大的对象字节数:

    !dumpheap –stat –min 85000          //查看大于85000bytes字节的对象

    !dumpheap -min 85000

    !dumpheap -mt 790fd8c4 -min 20000 -max 25000

    !dumpheap -type System.String -min 150 -max 200  //检查大小在 150 至 200 之间的所有字符串

    !dumpheap -mt 790fd8c4 -strings   //只输出字符串

    参数-short:

    !dumpheap -type System.String -min 6500 –short  //仅仅查询出对象的地址信息

    .foreach语句:

    .foreach (myAddr {!dumpheap -type System.String -min 6500 -short}){!dumpobj myAddr;.echo **************************}        // .echo 命令打印分割符

    .shell命令:

    .shell -i - -ci "!iisinfo.clientconns" FIND /c "Request active"

    .shell -i - -ci "!iisinfo.clientconns" FIND /c "<table"

    !dumpobj 04aa1a90     // 查看对象的详细信息

     !dumpclass 0x6c632e8  // 查看类型的详细信息

     !dumpmt -md 0x09750a8 // 查看方法表的详细信息

     !dumpmd 0x00975070    // 查看方法表项的方法描述的详细信息

     u 0x79b7c4eb          // 反汇编指定地址的指令

    [http://www.cnblogs.com/flier/archive/2004/07/08/22361.html]

    查看进程程序集加载情况:

    !dumpdomain

    将进程程序集导出

    !SaveModule 00992c5c z: empa.dll

    显示模块信息:

    !dumpmodule [-mt] 1c5a1098   //1c5a1098: module address

    查看native内存内容:

    MetaData start address: 1d3b09e4 (4184 bytes)

    dc 1d3b09e4 1d3b09e4+0n4184

    du 3cd30038 3cd30038 +1000

    [异常]

    查看托管线程

    !threads

    查看所有的Exception:

    !dumpheap –type Exception

    命令将打印出当前堆栈上正在被抛出的exception

    !pe/!PrintException

    打印出相应命令的详细信息及堆栈:

    !pe address

    查看某个具体的异常的详细信息

    !do [address]

    !do –nofields [address] //string类型简单输出格式

    查看对象的信息:

    !gcroot [address]

    打印出所有的同一个类型的Exception的信息

    .foreach(myVariable {!dumpheap -type System.ArgumentNullException -short}){!pe myVariable;.echo **}                

    //OutOfMemoryException? StackOverflowException? System.OutOfMemoryException?

    列出了GC 堆的大小 和G0,G1,G2 ,LOH的开始地址:

    !EEHeap [-gc] [-loader]

    !eeheap

    !eeheap –gc

    !eeheap -loader

    查看内存信息

    !name2ee * WindbgDemo.Program

    查看方法描述

    !dumpmd 00993034

    查看方法表信息

    !dumpmt -md 0099304c

    查看il

    !dumpil 00993034

    Dump文件

    C:Program FilesDebugging Tools for Windows (x86) adplus.vbs -hang -o C:dump -p 6876

    参数说明:

    ?-hang: 表示附加到目标进程,抓取 dump 镜像,然后解除。对应的参数是 -crash 崩溃模式,该参数会终止目标进程。

    ?-o: 指定 Dump 文件保存路径。

    ?-p: 指定目标进程 PID。

    Jitted代码:

    1. sxe ld:mscorjit.dll
    2. 2.    .loadby sos mscorwks
    3. !name2ee test.exe System.Program.Main
    4. ba w4 975070+0x04 "bp poi(975070+0x04);g"
    5. !clrstack

    Ngened代码:

    http://blog.joycode.com/gangp/archive/2004/04/28/20417.joy

    1、!analyze -v :用于分析挂掉线程的详细情形,错误原因。

    2、!locks :列出全部资源使用情况。

    3、!locks -v 0x???????? :特定地址的死锁分析。

    4、!thread 0x????????:特定线程详情。

    5、.thread 0x????????:转到某个线程堆栈。

    2.3.    ~

    查看系统当前线程,使用~*s命令切换线程,如需要切换到8号线程,可以使用命令:~8s

    0:004> ~

       0  Id: dd0.7c0 Suspend: 1 Teb: 7ffdf000 Unfrozen

       1  Id: dd0.1230 Suspend: 1 Teb: 7ffde000 Unfrozen

       2  Id: dd0.bc4 Suspend: 1 Teb: 7ffdd000 Unfrozen

       3  Id: dd0.1424 Suspend: 1 Teb: 7ffdc000 Unfrozen

    .  4  Id: dd0.ba8 Suspend: 1 Teb: 7ffdb000 Unfrozen

    2.4.    .load sos

    加载微软提供的调试扩展工具,可以更方便的调试托管代码。只有加载SOS之后,才能使用下面的这些命令。

    0:004> .load sos

    2.5.    !clrstack

    查看当前线程的调用栈,如果想查看所有进程的调用栈情况, 使用~*e !clrstack

    0:000> !clrstack

    OS Thread Id: 0x7c0 (0)

    ESP       EIP    

    002aee00 775564f4 [NDirectMethodFrameStandalone: 002aee00] System.Windows.Forms.SafeNativeMethods.MessageBox(System.Runtime.InteropServices.HandleRef, System.String, System.String, Int32)

    002aee1c 66fffd28 System.Windows.Forms.MessageBox.ShowCore(System.Windows.Forms.IWin32Window, System.String, System.String, System.Windows.Forms.MessageBoxButtons, System.Windows.Forms.MessageBoxIcon, System.Windows.Forms.MessageBoxDefaultButton, System.Windows.Forms.MessageBoxOptions, Boolean)

    002aeebc 66fff93e System.Windows.Forms.MessageBox.Show(System.String)

    002aeec4 006603ab TestCode4AQTime.Form1.button1_Click(System.Object, System.EventArgs)

    002aeee0 669d4170 System.Windows.Forms.Control.OnClick(System.EventArgs)

    002af04c 66a023b0 System.Windows.Forms.Button.WndProc(System.Windows.Forms.Message ByRef)

    002af058 66a084a0

    002af218 007c09e4 [NDirectMethodFrameStandalone: 002af218] System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG ByRef)

    002af228 66a18aee System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32, Int32, Int32)

    002af2c4 66a18757 System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)

    002af318 66a185a1 System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)

    002af348 669d5911 System.Windows.Forms.Application.Run(System.Windows.Forms.Form)

    002af35c 006600ae TestCode4AQTime.Program.Main()

    2.6.    !do(DumpObj)

    查看class对象内容。!do [对象的内存地址]

    0:000> !do 01e80d5c

    Name: System.String

    MethodTable: 68eb88c0

    EEClass: 68c7a498

    Size: 102(0x66) bytes

     (C:WindowsassemblyGAC_32mscorlib2.0.0.0__b77a5c561934e089mscorlib.dll)

    String: system.serviceModel.activation/diagnostics

    Fields:

          MT    Field   Offset                 Type VT     Attr    Value Name

    68ebab0c  4000096        4         System.Int32  1 instance       43 m_arrayLength

    68ebab0c  4000097        8         System.Int32  1 instance       42 m_stringLength

    68eb95a0  4000098        c          System.Char  1 instance       73 m_firstChar

    68eb88c0  4000099       10        System.String  0   shared   static Empty

        >> Domain:Value  003a5698:01e61198 <<

    68eb94f0  400009a       14        System.Char[]  0   shared   static WhitespaceChars

        >> Domain:Value  003a5698:01e6174c <<

    !dumpvc(dv) 命令查看Value类型对象,对应c#的struct对象

    2.7.    !dso(DumpStackObjects)

    查看栈上对象。

    0:000> !dso

    OS Thread Id: 0x7c0 (0)

    ESP/REG  Object   Name

    002aede0 01e61198 System.String   

    002aede4 01e995c4 System.String    Finished

    002aedf8 01e9760c System.Windows.Forms.MouseEventArgs

    002aee4c 01e995c4 System.String    Finished

    002aee90 01e9760c System.Windows.Forms.MouseEventArgs

    002aee94 01e995c4 System.String    Finished

    002aee98 01e87bfc System.Windows.Forms.Button

    002aeeb8 01e61198 System.String   

    002aeebc 01e88af0 System.EventHandler

    002aeec4 01e69a54 TestCode4AQTime.Form1

    002aeed0 01e87bfc System.Windows.Forms.Button

    002aeedc 01e9760c System.Windows.Forms.MouseEventArgs

    002aeee0 01e87d98 System.ComponentModel.EventHandlerList

    2.8.    !dumpheap

    查看托管堆内存对象信息。

    !dumpheap –stat  只输出统计信息(常用

    !dumpheap –type <partial type name> 只输出类型名和给出(部分)类型名称匹配的对象

    0:000> !dumpheap -stat

    total 4843 objects

    Statistics:

          MT    Count    TotalSize Class Name

    68ebaa5c       36         3776 System.Int32[]

    68728c6c       95         5320 System.Configuration.FactoryRecord

    68ebb010       32        10224 System.Collections.Hashtable+bucket[]

    68eb94f0       41        10544 System.Char[]

    68eba468      666        15984 System.Version

    68ebb330       17        25528 System.Byte[]

    68e94eec      231        41168 System.Object[]

    68eb88c0     1102        89616 System.String

    Total 4843 objects

    2.9.    !objsize

    查看对象实际占用内存大小

    0:000> !objsize 01e80d5c

    sizeof(01e80d5c) =          104 (        0x68) bytes (System.String)

    2.10. !gcroot

    查找对象引用关系

    0:000> !gcroot 01e80d5c

    Note: Roots found on stacks may be false positives. Run "!help gcroot" for

    more info.

    Scan Thread 0 OSTHread 7c0

    Scan Thread 2 OSTHread bc4

    DOMAIN(003A5698):HANDLE(Pinned):2f13e4:Root:02e65dd8(System.Object[])->

    01e6d8cc(System.Configuration.ClientConfigurationSystem)->

    01e6f22c(System.Configuration.RuntimeConfigurationRecord)->

    01e7481c(System.Collections.Hashtable)->

    01e7e760(System.Collections.Hashtable+bucket[])

    2.11. !da(DumpArray)

    查看数组对象

    0:000> !da 02e65dd8

    Name: System.Object[]

    MethodTable: 68e94eec

    EEClass: 68c7a8a0

    Size: 4096(0x1000) bytes

    Array: Rank 1, Number of elements 1020, Type CLASS

    Element Methodtable: 68eb84dc

    [0] null

    [1] null

    [2] 01e88f00

    [3] null

    [4] null

    [5] 01e88ef4

    [6] null

    [7] null

    [8] null

    2.12. !threads

    列出当前进程中的托管线程,可以查看托管线程和系统线程的对应关系。

    0:004> !threads

    ThreadCount: 2

    UnstartedThread: 0

    BackgroundThread: 1

    PendingThread: 0

    DeadThread: 0

    Hosted Runtime: no

                                          PreEmptive   GC Alloc           Lock

           ID OSID ThreadOBJ    State     GC       Context       Domain   Count APT Exception

       0    1  e6c 0026aeb8      6020 Enabled  018bd010:018bdfe8 00265698     0 STA

       2    2  c08 002790f0      b220 Enabled  00000000:00000000 00265698     0 MTA (Finalizer)

     

    2.13. !eeheap

    通过!eeheap,可以查看CLR堆的使用情况。

    !eeheap –gc:只查看GC堆的输出结果。

    !eeheap –loader:查看和AppDomains关联的各种私有堆的输出结果。

    0:004> !eeheap -loader

    Loader Heap:

    --------------------------------------

    System Domain: 726ee1f8

    LowFrequencyHeap: Size: 0x0(0)bytes.

    HighFrequencyHeap: 00232000(8000:1000) Size: 0x1000(4096)bytes.

    StubHeap: 0023a000(2000:2000) 00c50000(10000:3000) Size: 0x5000(20480)bytes.

    Virtual Call Stub Heap:

      IndcellHeap: Size: 0x0(0)bytes.

      LookupHeap: Size: 0x0(0)bytes.

      ResolveHeap: Size: 0x0(0)bytes.

      DispatchHeap: Size: 0x0(0)bytes.

      CacheEntryHeap: Size: 0x0(0)bytes.

    Total size: 0x6000(24576)bytes

    --------------------------------------

    Shared Domain: 726edb48

    LowFrequencyHeap: 00430000(2000:1000) Size: 0x1000(4096)bytes.

    HighFrequencyHeap: 00432000(8000:1000) Size: 0x1000(4096)bytes.

    StubHeap: 0043a000(2000:1000) Size: 0x1000(4096)bytes.

    Virtual Call Stub Heap:

      IndcellHeap: 00480000(2000:1000) Size: 0x1000(4096)bytes.

      LookupHeap: 00485000(2000:1000) Size: 0x1000(4096)bytes.

      ResolveHeap: 0048b000(5000:1000) Size: 0x1000(4096)bytes.

      DispatchHeap: 00487000(4000:1000) Size: 0x1000(4096)bytes.

      CacheEntryHeap: 00482000(3000:1000) Size: 0x1000(4096)bytes.

    Total size: 0x7000(28672)bytes

    --------------------------------------

    Domain 1: 265698

    LowFrequencyHeap: 00410000(2000:2000) 006c0000(10000:1000) Size: 0x3000(12288)bytes.

    HighFrequencyHeap: 00412000(8000:5000) Size: 0x5000(20480)bytes.

    StubHeap: 0041a000(2000:1000) Size: 0x1000(4096)bytes.

    Virtual Call Stub Heap:

      IndcellHeap: 00420000(2000:1000) Size: 0x1000(4096)bytes.

      LookupHeap: 00426000(1000:1000) Size: 0x1000(4096)bytes.

      ResolveHeap: 0042a000(6000:2000) Size: 0x2000(8192)bytes.

      DispatchHeap: 00427000(3000:1000) Size: 0x1000(4096)bytes.

      CacheEntryHeap: 00422000(4000:1000) Size: 0x1000(4096)bytes.

    Total size: 0xe000(57344)bytes

    --------------------------------------

    Jit code heap:

    LoaderCodeHeap: 004e0000(10000:1000) Size: 0x1000(4096)bytes.

    Total size: 0x1000(4096)bytes

    --------------------------------------

    Module Thunk heaps:

    Module 72741000: Size: 0x0(0)bytes.

    Module 00432358: Size: 0x0(0)bytes.

    Module 00432010: Size: 0x0(0)bytes.

    Module 00412c5c: Size: 0x0(0)bytes.

    Module 66701000: Size: 0x0(0)bytes.

    Module 672e1000: Size: 0x0(0)bytes.

    Module 67f61000: Size: 0x0(0)bytes.

    Module 65ab1000: Size: 0x0(0)bytes.

    Module 65571000: Size: 0x0(0)bytes.

    Total size: 0x0(0)bytes

    --------------------------------------

    Module Lookup Table heaps:

    Module 72741000: Size: 0x0(0)bytes.

    Module 00432358: Size: 0x0(0)bytes.

    Module 00432010: Size: 0x0(0)bytes.

    Module 00412c5c: Size: 0x0(0)bytes.

    Module 66701000: Size: 0x0(0)bytes.

    Module 672e1000: Size: 0x0(0)bytes.

    Module 67f61000: Size: 0x0(0)bytes.

    Module 65ab1000: Size: 0x0(0)bytes.

    Module 65571000: Size: 0x0(0)bytes.

    Total size: 0x0(0)bytes

    --------------------------------------

    Total LoaderHeap size: 0x1c000(114688)bytes

    =======================================

    0:004> !eeheap -gc

    Number of GC Heaps: 1

    generation 0 starts at 0x01881018

    generation 1 starts at 0x0188100c

    generation 2 starts at 0x01881000

    ephemeral segment allocation context: none

     segment    begin allocated     size

    01880000 01881000  018bdff4 0x0003cff4(249844)

    Large object heap starts at 0x02881000

     segment    begin allocated     size

    02880000 02881000  02886de8 0x00005de8(24040)

    Total Size   0x42ddc(273884)

    ------------------------------

    GC Heap Size   0x42ddc(273884)

    2.14. 转储进程

    直接使用微软提供的aplus.vbs脚本转储w3wp.exe进程

    Cscript adplus.vbs –hang –pn w3wp.exe –o <Dump存储目录> -quiet –do

    使用Windbg命令转储进程

    .dump /f <Dump存储文件>

    第三章 常见问题

    3.1. OutOfMemory

    解决思路:

    使用!dumpheap –stat命令检查托管堆对象。

    使用gcroot查找数量/大小不正常对象的引用链,以明确对象没被GC回收的原因

    3.2. 系统缓慢&HighCPU&单点效率异常

    解决思路:

    使用!clrstack命令,多次抓取系统调用栈。

    比较调用栈停留位置,找到可疑处。

    通过!do&!dso查看栈变量,判断代码调用栈停留位置效率低下原因。

    第四章 应用示例

    示例1: 缓存对象

    1. 检查缓存大小

    !dumpheap –stat –type System.Web.Caching.Cache  //得到了 System.Web.Caching.Cache 对象的方法表

    !dumpheap –mt 1230494c     //得到1230494c方法表中所有对象

    !objsize 03392d20       //得到当前地址对应对象的大小

    2. 什么内容被缓存了?

    !dumpheap –stat –type System.Web.Caching   //查看 CacheEntrys 对象

    !dumpheap -mt 12306320  //查看CacheEntrys的方法表MT

    !do 076b42dc          //检查对象的所有内容, 之后

    示例2: 挂起

    检查堆栈信息

    检查本地的堆栈信息:

    ~* kb 2000

    检查 dotnet 堆栈信息:

    ~* e!clrstack                   // Do you see any patterns or recognize any of the callstacks that suggests a thread is waiting for a synchronization mechanism?

      看看有多少调用堆栈里有Monitor.Enter:

    .shell -ci "~* e !clrstack" FIND /C Monitor.Enter

    跟踪诊断挂起现象

    检查等待锁的线程ID列表:

    !syncblk                    //(提示:MonitorHeld = 1 代表拥有者,2为等待者)

    查看一个等待线程的状态:

    ~5s         (切换到线程 5,用真实的线程ID替换5即可)
    kb 2000   (检查本地堆栈信息)
    !clrstack  (查看dotnet 堆栈信息)

    !clrstack –p (查看dotnet 堆栈信息,包括参数内存地址)

    !clrstack –a

    示例3: 查看缓存占用情况

    查看Cache占用内存情况:

    !name2ee System.Web.dll System.Web.Caching.Cache

    0:000> !name2ee System.Web.dll System.Web.Caching.Cache

    Module: 65f21000 (System.Web.dll)

    Token: 0x020000fa

    MethodTable: 66148d24

    EEClass: 65f86838

    Name: System.Web.Caching.Cache

    !dumpheap –mt [MethodTable]  //查看托管堆中对象类型

    !objsize 06952248  //查看对象大小

    示例4: 内存调试

    首先看看GC heap的大小,和dump 文件比较一下。

    这个 !eeheap 命令列出了GC 堆的大小 和G0,G1,G2 ,LOH的开始地址。

    0:001> !eeheap –gc

    generation 0 starts at 0x0110be64

    generation 1 starts at 0x01109cd8

    generation 2 starts at 0x01021028

     segment    begin allocated     size

    01020000 01021028 0110de70 000ece48(970312)

    Total Size   0xece48(970312)

    ------------------------------

    large block 0x11e1fc04(300022788)

    large_np_objects start at 17b90008

    large_p_objects start at 02020008

    ------------------------------

    GC Heap Size 0x11f0ca4c(300993100)

    在这里GC 堆是300M左右,dump文件是358M。

    使用 !dumpheap –stat 命令来查看占用了空间的托管对象。

    0:001> !dumpheap -stat

    Bad MethodTable for Obj at 0110d2a4

    Last good object: 0110d280

    total 14459 objects

    Statistics:

          MT    Count TotalSize Class Name

    3c6185c        1        12 System.Web.UI.ValidatorCollection

    3c2e110        1        12 System.Web.Configuration.MachineKeyConfigHandler

    3c29778        1        12 System.Web.Configuration.HttpCapabilitiesSectionHandler

    3c23240        1        12 System.Web.SafeStringResource

    … …

    D12f28      1133     46052 System.Object[]

    153cb0        88     76216 Free

    321b278       85    178972 System.Byte[]

    d141b0      6612    416720 System.String

    Total 14459 objects

    使用!gcroot 16220018从LOH上得到更多对象的信息:

    0:001> !gcroot 16220018

    Scan Thread 1 (4e8)

    Scan Thread 5 (bb0)

    Scan Thread 6 (d0)

    Scan Thread 10 (43c)

    Scan Thread 11 (308)

    Scan Thread 12 (6e4)

    Scan HandleTable 14e340

    Scan HandleTable 150e40

    Scan HandleTable 1a6fa8

    HANDLE(Strong):37411d8:Root:020784d8(System.Object[])-

    >0108b504(System.Web.HttpRuntime)->0108b9d0(System.Web.Caching.CacheSingle)-

    >0108ca68(System.Web.Caching.CacheUsage)->0108ca78(System.Object[])-

    >0108cb3c(System.Web.Caching.UsageBucket)-

    >010f95fc(System.Web.Caching.UsageEntry[])-

    >01109be8 (System.Web.Caching.CacheEntry)->00000000()

    要找出System.Web.Caching.Cache的地址,请使用 !name2ee命令,这个命令接受2个参数 程序集的名字和全类名:

    0:001> !name2ee System.Web.dll System.Web.Caching.Cache

    --------------------------------------

    MethodTable: 03887998

    EEClass: 03768814

    Name: System.Web.Caching.Cache

    --------------------------------------

    EEClass 是一个用来表示.net 类的内部结构。

    取得托管堆中的某个对象的类型,使用 !dumpheap –mt MethodTable地址 的方式来获得:

    0:001> !dumpheap -mt 03887998

     Address       MT     Size

    0108b8ac 03887998       12

    Bad MethodTable for Obj at 0110d2a4

    Last good object: 0110d280

    total 1 objects

    Statistics:

          MT    Count TotalSize Class Name

     3887998        1        12 System.Web.Caching.Cache

    Total 1 objects

    large objects

     Address       MT     Size

    total 0 large objects

    查看 System.Web.Caching.Cache 的大小,使用 !objsize 0108b8ac:

    0:001> !objsize 0108b8ac

    sizeof(0108b8ac) = 300126128 (0x11e38fb0) bytes (System.Web.Caching.Cache)

    修正代码,把缓存移除。重新装载 dump文件,加载模块,使用 !eeheap –gc 来看看托管堆的大小:

    0:000> !eeheap -gc

    generation 0 starts at 0x012cc0e4

    generation 1 starts at 0x012afde8

    generation 2 starts at 0x011c1028

     segment    begin allocated     size

    011c0000 011c1028 012d6000 00114fd8(1134552)

    Total Size 0x114fd8(1134552)

    ------------------------------

    large block 0x8060(32864)

    large_np_objects start at 00000000

    large_p_objects start at 021c0008

    ------------------------------

    GC Heap Size 0x11d038(1167416)

    dump 显示 GC 堆的大小是1M,不是222M,这表示除了1M其它的都被收集了。

    示例5: 内存泄露跟踪

    I.查看内存使用概要:

    !address -summary

    0:000> !address -summary

    --------------------   Usage SUMMARY --------------------------

        TotSize (      KB)     Pct(Tots) Pct(Busy)   Usage

       373b7000 (    904924) : 21.58%    85.85%    : RegionUsageIsVAD

       bfa89000 ( 3140132) : 74.87%    00.00%      : RegionUsageFree

        76e6000 (    121752) : 02.90%    11.55%    : RegionUsageImage

         67c000 (    6640) : 00.16%    00.63%      : RegionUsageStack

              0 (       0) : 00.00%    00.00%      : RegionUsageTeb

        144a000 (   20776) : 00.50%    01.97%      : RegionUsageHeap

              0 (       0) : 00.00%    00.00%      : RegionUsagePageHeap

           1000 (       4) : 00.00%    00.00%      : RegionUsagePeb

           1000 (       4) : 00.00%    00.00%      : RegionUsageProcessParametrs

           2000 (       8) : 00.00%    00.00%      : RegionUsageEnvironmentBlock

           Tot: ffff0000 (4194240 KB) Busy:   40567000 (1054108 KB)

    --------------------   Type SUMMARY --------------------------

        TotSize (      KB)     Pct(Tots)  Usage

       bfa89000 ( 3140132) : 74.87%   :

        834e000 (    134456) : 03.21%   : MEM_IMAGE  [总共内存占用百分比]

         95a000 (    9576) : 00.23%   : MEM_MAPPED

       378bf000 (    910076) : 21.70%   : MEM_PRIVATE

    --------------------   State SUMMARY --------------------------

        TotSize (      KB)     Pct(Tots)  Usage

       34bea000 (    864168) : 20.60%   : MEM_COMMIT

       bfa89000 ( 3140132) : 74.87%   : MEM_FREE

        b97d000 (    189940) : 04.53%   : MEM_RESERVE

    Largest free   region: Base 80010000 - Size 7fefa000 (2096104 KB)

      这里有非常多的信息,但所有的这些都不是这么明显的。相信我,让我们花一些时间在这里。在任何一个案例中,我用这个来帮助我指出我需要查看哪些地方,所以我不介意它要花费多少,即使就是一个概述的结果。

    一些要注意的地方:

    上面一屏显示了按照类型不同而分类显示的由进程使用的内存。第一部分是按照区域类型来划分的,它按照什么样子的分配类型告诉你信息。最常遇到的一个类型是VAD = Virtual Alloc, Image = dlls 和 exes,Heap = heaps the process owns,从WinDbg的帮助中可以得到更多的信息。接着下面是按IMAGE, MAPPED  或 PRIVATE 的类型来列出,最后一部分是按已提交(also committed,就是指实际已经分配的)或保留(reserved)的方式来列出它们。

    RegionUsageheap,代表的是NT heaps;MEM_COMMIT和MEM_RESERVE加起来,是virtual   memory。

    Tot: ffff0000 (4   194 240 kb) :的意思是我总共有4GB的虚拟内存地址空间提供给这个应用程序。32位系统上,你可以寻地4GB的空间,典型的是2GB的用户模式的内存空间,所以一般你会看到2GB而不是这里的4GB,在64位上,运行一个32位的进程会得到完全的4GB的空间,所以我这里看到的是4GB。

    Busy: 40567000 (1   054 108 kb)  是我们已经使用的(已经分配的)。

    MEM_PRIVATE是一个私有的内存,它不和其他进程共享内存,不是映射到文件的内存。不要把这个和性能计数器中的Private Bytes混淆。这里的MEM_PRIVATE 是保留+已提交(即已分配的)(reserved + committed)的字节数,另外那个Private   Bytes 是申请/已提交(allocated/committed)的字节数。

    MEM_PRIVATE 是已经提交(已经分配)的内存(不一定是 private的),这个可能是最接近你得到的Private Bytes的。

    MEM_RESERVE 是已经保留的,但没有实际分配的,未提交的内存。所有已经分配的内存也是定义为保留的,所以如果你查看所有保留的内存(最接近你得到的virtual bytes),你必须加上MEM_COMMIT和   MEM_RESERVE,它是显示在Busy 中的那个数字。你自己把数字加上后比对一下看看。

    Q:哪个值最能代表如下两个指标?

    ·Private Bytes           A: MEM_COMMIT

    ·Virtual Bytes           A: Busy

    Q:大部分的内存都去哪里了?(哪个区域)

    A:在这里,大约904MB是为VAD保留的,VAD是dotnet对象存放的地方,因为GC堆是virtual   allocs 分配的。

    Q:Busy,Pct(Busy),Pct(Tots)是什么意思?

    A:Pct(Tots) 显示的是整个虚拟地址空间中分配给不同区域类型的百分比。Pct(Busy)显示的是保留的内存中分配给不同区域的百分比。Pct(busy) 很显然是我最关心的一个。

    Q:MEM_IMAGE 是什么意思?

    A:从帮助文件中我们知道:这个是表示从一个可执行的映射文件的一部分映射到的内存。换句话说 就是dll 或一个exe 文件的内存映射。

    Q:哪个区域的.net 内存是适宜的,为什么?

    A:在RegionUsageIsVAD,理由如上。

      从性能计数器中我们看到#Bytes   in all Heaps 跟随着Private bytes的增长而增长,那说明了内存的增加几乎都是.net 的使用而增加的,进而我们转化为为什么.net 的GC堆(heap)始终在增长。

    II.运行 !eeheap –gc 来查看.net GC 堆的大小

    0:000> !eeheap   -gc

    Number of GC   Heaps: 2

    ------------------------------

    Heap 0 (001aa148)

    generation 0   starts at 0x32f0639c

    generation 1   starts at 0x32ae3754

    generation 2   starts at 0x02eb0038

    ephemeral segment   allocation context: none

     segment      begin allocated     size

    001bfe10   7a733370  7a754b98 0x00021828(137256)

    001b0f10   790d8620  790f7d8c 0x0001f76c(128876)

    …..

    Large object heap   starts at 0x0aeb0038

     segment      begin allocated     size

    0aeb0000 0aeb0038  0aec0b28 0x00010af0(68336)

    Heap Size  0x15fd1310(368907024)

    ------------------------------

    Heap 1 (001ab108)

    generation 0   starts at 0x36e665bc

    generation 1   starts at 0x36a28044

    generation 2   starts at 0x06eb0038

    ephemeral segment   allocation context: none

     segment      begin allocated     size

    06eb0000   06eb0038  0aea58d4 0x03ff589c(67066012)

    ……

    Large object heap   starts at 0x0ceb0038

     segment      begin allocated     size

    0ceb0000   0ceb0038  0ceb0048 0x00000010(16)

    Heap Size  0x15ab1570(363533680)

    ------------------------------

    GC Heap Size  0x2ba82880(732440704)

    Q:总共有多少个Heap,为什么?

    A:这里有两个堆,因为我们运行在多核进程模型中。

    Q:有多少内存被保存在了.net GC 堆中?拿#Bytes   in all Heaps比较一下。

    A:GC的堆大小是:GC Heap Size 0x2ba82880(732 440 704),它和性能计数器中的bytes in all heaps很接近。

    Q:large object heap 上有多少内存?提示:把large   object heap段上的合计加起来,和性能计数器中的Large Object Heap Size 比较一下。

    A:它是非常小的,所以LOH看起来不是问题所在,大小是68 336 + 16 bytes

    III. 运行 !dumpheap –stat 来输出所有的以统计式样表示的.net 对象

    Q:查看 5 到10个使用了大部分内存的对象,思考一下是什么泄露了?

    A:

    66424cf4       37        57276 System.Web.Caching.ExpiresEntry[]

    663b0cdc     4001       192048   System.Web.SessionState.InProcSessionState

    7912d8f8     3784       255028 System.Object[]

    7912d9bc      820       273384   System.Collections.Hashtable+bucket[]

    6639e4c0     4037       290664 System.Web.Caching.CacheEntry

    0fe11cf4    36000       576000 Link

    790fdc5c    36161       723220 System.Text.StringBuilder

    001a90c0     1105        7413924      Free

    790fd8c4    51311      721773112 System.String

    Total 163943   objects

    大部分的内存是被strings用掉了,这个不太正常,虽然strings 在应用中是最常见的,但是大约721MB的显然有点怪异,并且有3600个Links(无论它们是什么),看起来有点奇怪。特别是因为有差不多数量的stringbuilds 出现在dump中。

    Q:“size”那个行显示了什么?例如,“size”这行包含了什么?

    A:如果我们用命令!do 把Link 对象输出来,我们看到有一个指针指向stringbuilder(url)和一个指针指向string(name),link对象的大小是16B,这个大小仅仅包含了指针的大小和其他一些开销(methos table 等)。

    如果你运行 !objsize ,你会看见大小是高达20144   B ,这个大小是包含成员变量的,比如Link对象的大小和它引用的所有对象。

    你看到了什么通过!dumpheap 输出的16B的每一个link。它不包含成员变量的大小是由一些不同原因的:

     1)它将要花费很长的时间去计算大小。

     2) 一些对象(假如是A和B)可能都指向C对象,如果你使用 !objsize 计算A 和B的大小,他们都会包含C的大小,所以size这个列的值会变得很复杂难以计算。

     3) 在这个例子中Link的大小size看起来似乎是正常的。因为一个link对象包含一个url和一个name。但是如果一个web 控件可能会包含一个成员变量 _parent ,如果你运运行   !objsize ,这样就会包含父对象(page)那就显然是不合适的。

    0:000> !do   371d44cc

    Name: Link

    MethodTable:   0fe11cf4

    EEClass: 0fde5824

    Size: 16(0x10)   bytes

     (C:WINDOWSMicrosoft.NETFrameworkv2.0.50727

    Temporary ASP.NET   Filesuggybits27906ccf5f91899App_Code.wbwztx_4.dll)

    Fields:

          MT      Field   Offset                 Type VT     Attr      Value Name

    790fdc5c  4000006        4 ...ext.StringBuilder  0 instance 371d44dc url

    790fd8c4  4000007        8        System.String  0 instance 02f13cd8 name

    0:000>   !objsize 371d44cc

    sizeof(371d44cc)   =        20144 (      0x4eb0) bytes (Link)

    通常,我不推荐立刻查看在你的这个非常简单的dump文件中,在该命令输出的底部的strings,因为:

     · strings 这一行的“size”是实际的字符串string的有内容的真实大小。如果你和DataSet比较,这个“size”只是包含了行和列的指针,并没有包含行和列的内存。所以DataSet这个对象的大小几乎总是非常的小的。

     · string 字符串在大部分的对象中几乎是叶子节点,例如,dataset包含字符串,aspx页面包含字符串,session 变量也包含字符串。所以,在一个应用中几乎都是字符串。

    然而在这个例子中,字符串有这么多,占有了那么多的内存。如果我们不查到其他一些阻止了我们的东西,那我们可能就要沿着string 这条路走下去了。

    IV. 把各种不同大小的string 都输出来

    得到string的 MT(method table),!dumpheap –stat 的输出结果的第一列。

    !dumpheap -mt <string MT> -min 85000 -stat

    !dumpheap -mt <string MT> -min 10000 -stat

    !dumpheap -mt <string MT> -min 20000 -stat

    !dumpheap -mt <string MT> -min 30000 -stat

    !dumpheap -mt <string MT> -min 25000 -stat

      Q:大部分的string’在一个什么样的范围内?

       A:在 20000 和 25000 字节之间。

    V. 把那个范围内的string 输出来。

       !dumpheap -mt <string MT> -min 20000 -max 25000

       在这里,它们中的大部分是一模一样的大小的,这是一个指引我们向下前进的线索。

    0:000> !dumpheap -mt 790fd8c4 -min 20000 -max 25000

    ------------------------------

    Heap 0

     Address       MT     Size

    02f1412c   790fd8c4    20020    

    02f2d96c   790fd8c4    20020    

    02f327c4   790fd8c4    20020    

    02f3761c   790fd8c4    20020    

    02f3c474   790fd8c4    20020    

    02f412cc   790fd8c4    20020    

    02f46124   790fd8c4    20020    

    02f4af7c   790fd8c4    20020    

    02f4fdd4   790fd8c4    20020    

    02f54c2c   790fd8c4    20020    

    ...

    VI.把它们中的一些输出来看看里面是什么

    !do <address of string>  ,地址是 !dumpheap -mt 输出的第一列。

    0:000> !do 02f327c4

    ...

    String: http://www.sula.cn

    ...

    Q:这些string里面包含的是什么?

    A:好像link.aspx 页面显示了link对象。

    VII. 拣几个,看看它们被根化(rooted)到哪里(即为什么它们不会被回收)。注意你可能需要尝试不同的几个才行.

    !gcroot <address of string>

    0:000> !gcroot 02f327c4

    Note: Roots found on stacks may be false positives. Run "!help gcroot" for

    more info.

    Scan Thread 16 OSTHread 1948

    Scan Thread 20 OSTHread 1b94

    Scan Thread 21 OSTHread 1924

    Scan Thread 22 OSTHread 188c

    Scan Thread 14 OSTHread 1120

    Scan Thread 24 OSTHread 13f8

    Finalizer queue:Root:02f327a0(Link)->

    02f327b0(System.Text.StringBuilder)->

    02f327c4(System.String)

    Q:它们被根化到哪里?为什么?

    A:这个string是一个string builder 类型的成员变量,它表现的是一个link的成员变量(url),link 对象被根化在终结器队列中,那就是说他正在等待被终结。

    检查终结器队列(finalizer queue)和终结线程(finalizer thread

    1)查看终结器队列

    !finalizequeue

    0:000> !finalizequeue

    SyncBlocks to be   cleaned up: 0

    MTA Interfaces to   be released: 0

    STA Interfaces to   be released: 0

    ----------------------------------

    ------------------------------

    Heap 0

    generation 0 has   221 finalizable objects (0f44a764->0f44aad8)

    generation 1 has   0 finalizable objects (0f44a764->0f44a764)

    generation 2 has   45 finalizable objects (0f44a6b0->0f44a764)

    Ready for   finalization 18009 objects (0f44aad8->0f45c43c)

    ------------------------------

    Heap 1

    generation 0 has   338 finalizable objects (0f45d840->0f45dd88)

    generation 1 has   4 finalizable objects (0f45d830->0f45d840)

    generation 2 has   36 finalizable objects (0f45d7a0->0f45d830)

    Ready for   finalization 17707 objects (0f45dd88->0f46f234)

    Statistics:

          MT      Count    TotalSize Class Name

    663a1fc8        1           12   System.Web.Configuration.ImpersonateTokenRef

    79116758        1           20   Microsoft.Win32.SafeHandles.SafeTokenHandle

    791037c0        1           20   Microsoft.Win32.SafeHandles.SafeFileMappingHandle

    79103764        1             20 Microsoft.Win32.SafeHandles.SafeViewOfFileHandle

    6639c104        1           20   System.Web.PerfInstanceDataHandle

    663f6b5c        1           28   System.Web.Security.FileSecurityDescriptorWrapper

    663a105c        1           32 System.Web.Compilation.CompilationMutex

    7910b630        2           40   System.Security.Cryptography.SafeProvHandle

    79112728        5          100   Microsoft.Win32.SafeHandles.SafeWaitHandle

    790fe704        2          112 System.Threading.Thread

    7910a5c4        2          120   System.Runtime.Remoting.Contexts

    ...

    Q:在这个命令的输出中列出了什么对象?

    A:所有具有终结/析构器的都被注册到终结器队列中,当对象被垃圾收集时,终结器会运行析构函数,否则在dispose函数中终结过程会挂起。

    Q:有多少个对象是出于“ready for finalization”,它是什么意思?

    A:大约有36000个,这些对象是要被垃圾收集的,正在等待被终结。如果ready for finalization大于0 但没有显示任何信息,这是一个说明终结器线程被堵塞的最好时机。所以这些对象被堵住了等待终结,他们消耗了大部分的内存。

    2)  找出终结线程,了解它正在干什么,运行!threads ,在列出的线程中查找带有“(Finalizer)”的线程。

    3)  切换到终结线程,检查托管的和本地(原生)的调用堆栈。

    ~5s   (把5 替换成真实的终结线程(finalizer thread)的ID号)

    kb 2000

    !clrstack

    0:000>   !threads

    ...

      20      2 1b94 001ac2c0   200b220   Enabled  00000000:00000000   001ccc80     0 MTA (Finalizer)

    ...

    0:020>   !clrstack

    OS Thread Id:   0x1b94 (20)

    ESP       EIP      

    02a0f8fc 7d61cca8   [HelperMethodFrame: 02a0f8fc] System.Threading.Thread.SleepInternal(Int32)

    02a0f950 0fe90ce8   Link.Finalize()

    02a0fc1c 79fbcca7   [ContextTransitionFrame: 02a0fc1c]

    02a0fcec 79fbcca7   [GCFrame: 02a0fcec]

    Q:什么对象正在被终结?

    A:看起来是一个link 对象。

    Q:它正在干什么? 为什么这个会导致高内存使用率?

    A:终结link对象的终结器线程因为sleep 被堵住了。意味着终结器被堵住,进程中没有东西可以被终结。因而等待终结的进程都会仍然在内存中直到终结器醒来它们被终结为止。

    示例6: 线程状态

    !threads命令看看当前CLR中有哪些线程正在执行

    以下为引用:


    0:004> !threads
    ThreadCount: 2
    UnstartedThread: 0
    BackgroundThread: 1
    PendingThread: 0
    DeadThread: 0
                                 PreEmptive   GC Alloc               Lock
           ID ThreadOBJ    State     GC       Context       Domain   Count APT Exception
      0   6ec 0014e708      6020 Enabled  00000000:00000000 00148a90     0 STA
      2   a68 00157618      b220 Enabled  00000000:00000000 00148a90     0 MTA (Finalizer)

    前面5个计数器分别表示托管(managed)线程、未启动线程、后台线程、阻塞线程和僵死线程的数量。
        下面的列表是当前托管线程的详细信息:第一个域是WinDbg的线程编号;ID是Win32线程ID;ThreadObj是线程的对象;State是一个标志位,以后再详细介绍;PreEmptive GC表示GC是否与此线程协作;GC Alloc Context是GC的相关信息;Domain是线程所在AppDomain;Lock Count是线程拥有锁的计数器;APT是线程类型,沿用COM中STA/MTA/NTA(netural)的概念;最后的Exception表示线程类型,除了普通的用户线程外还有finalizer、GC、Theadpool Worker和Threadpool Completion Port,其功能与名字相符.

    示例7: 调试.net代码

    1. !name2ee SimpleSample.exe SimpleSample.Program.Main

    显示方法相关地址

    0:004> !name2ee SimpleSample.exe SimpleSample.Program.Main

    Module: 00982c5c (SimpleSample.exe)

    Token: 0x06000005

    MethodDesc: 00983000

    Name: SimpleSample.Program.Main()

    JITTED Code Address: 01220070

    2. !dumpil 00983000

    显示方法被C#编译器编译之后的IL代码

    0:004> !dumpil 00983000

    ilAddr = 004020c4

    IL_0000: nop

    IL_0001: ldstr "Any key continue... ... "

    IL_0006: call System.Console::WriteLine

    IL_000b: nop

    IL_000c: call System.Console::Read

    IL_0011: pop

    IL_0012: call SimpleSample.Program::getcharBuffer

    IL_0017: stloc.0

    IL_0018: ldloc.0

    IL_0019: call SimpleSample.Program::changeto4p

    IL_001e: nop

    IL_001f: ldloc.0

    IL_0020: call System.Console::WriteLine

    IL_0025: nop

    IL_0026: call System.Console::Read

    IL_002b: pop

    IL_002c: call System.Console::Read

    IL_0031: pop

    IL_0032: ret

    3. !u 01220070

    显示JIT编译了的方法的本地代码

      Other:

      !dumpmt -md 00983024       //得到类的成员函数详细信息

      !dumpheap -stat              //显示程序中所有对象的统计信息

      !dumpheap -mt 00983024     //该命令显示MethodTable的详细信息

      !gcroot 012919b8            //来显示一个实例的所属关系

      !dumpobj(do) 012a3904      //显示一个对象的具体内容

      !ObjSize 012a1ba4          //对象实际在内存中的大小

      !DumpArray          

         //查看数组信息 (http://www.pin5i.com/showtopic-15919.html) 

     !dumpheap -type Exception   //查看异常信息

    示例8: 查看方法代码

    !ip2md 05600dfd   --05600dfd: 表示EIP

        MethodDesc: 02429048

        Method Name: DataLayer.GetFeaturedProducts()

        Class: 055b18ac

        MethodTable: 0242905c

        mdToken: 06000008

        Module: 024285cc

        IsJitted: yes

        m_CodeOrIL: 05600dd0

    I.根据md来看:!dumpil 02429048 (这个地址是上面步骤f中的输出的第一行

    MethodDesc的值)

    II. 根据native code来看:!u 05600dd0 (这个地址是上面步骤f中的输出的最后一行的m_CodeOrIL的值)

    III.根据module来看:!dumpmodule 024285cc (这个地址是上面步骤分钟的输出的

    倒数第三行的Module的值)

    附: WinDbg / SOS Cheat Sheet

     

    Environment

    Attach to   process

    F6

    Detach from a   process

    .detach

    Break debugger   execution

    Ctrl-Break

    Continue   debugger execution

    g

    Exit WinDbg

    q

    Clear the screen

    .cls

    Getting   Help

    Debugger commands

    ?

    Debugger   commands

    .help

    Online help file

    .hh command

    Help on   extension on top of chain

    !help

    Help on specific   extension command

    !help command

     

    Issuing   Commands

    Scroll through   command history

    [up], [down],   [enter]

    Paste into   command window

    [right-click]

     

    Examining   the Unmanaged Environment

    List loaded   modules with full path

    lmf

    List loaded   modules with last modified timestamp

    lmt

    List unmanaged   threads

    ~

    Select active   thread

    ~thread_id s

    View call stack

    k

    View thread CPU   consumption

    !runaway

    Set a breakpoint

    bp

    Dump small   memory image

    .dump path

    Dump large   memory image

    .dump /ma path

     

    Loading   SOS

    Load SOS for   .NET 1.x

    .load clr10sos

    Load SOS for   .NET 2.0

    .loadby sos   mscorwks

     

    Examining   the Managed Environment

    Dump runtime   type information

    !dumpruntimetypes

    View managed   threads

    !threads

    View managed   call stack

    !clrstack

    View combined   managed / unmanaged callstack

    !dumpstack

    View function   call arguments

    !clrstack –p

    View local   variables

    !clrstack –l

    View object dump

    !do address

    View array dump

    !da address

    View object size   (including children)

    !objsize address

    View heap usage   by type

    !dumpheap -stat

    View heap usage   filtered by type

    !dumpheap -type   type

    View GC roots of   object instance

    !gcroot address

    View managed   sync blocks

    !syncblk

    View managed   thinlocks (CLR 2.0)

    !dumpheap   –thinlock

    View information   on most recent exception

    !printexception

    Set a breakpoint

    !bpmd module   method

     

     

    Type

    Explanation

    ESP

    ESP=Extended Stack Pointer, Object is in   use on a stack

    DOMAIN(001CCE68):HANDLE(Strong)

    Strong reference, Typically a static   variable

    DOMAIN(001CCE68):HANDLE(WeakLn)

    Weak Long Handle, A weak reference that   is tracked through finalization (can be resurrected) 

    DOMAIN(001CCE68):HANDLE(WeakSh)

    Weak Short Handle, A weak reference,   can't be resurrected

    DOMAIN(001CCE68):HANDLE(Pinned)

    Pinned object, pinned at a specific   address, can't move around during garbage collection.

    DOMAIN(001CCE68):HANDLE(RefCnt)

    Reference count, referenced as long   as the reference count is > 0.

    第五章 sos.dll 扩展命令

    命令

    描述

    BPMD [<module name>   <method name>] [-md <MethodDesc>]

    建立一个断点在指定模块的指定方法上。

    如果指定模块和方法尚未被载入,该命令等到该模块被载入并且被即时(just-in-time)编译的通知后再建立断点。

    CLRStack [-a] [-l]   [-p]

    只提供托管代码的栈跟踪。

    -p 选项显示托管函数的参数。

    -l 选项显示在一个框架里局部变量的信息。SOS调试扩展无法检索局部变量的名字,所以局部变量的输出格式为<local   address> = <value>。

    -a (all) 选项是-l-p组合的快捷方式。

    在x64和基于IA-64的平台上,SOS调试扩展不显示过渡框架(Transition Frames)。

    COMState

    列出每个线程COM单元模型和可用的上下文指针。

    DumpArray [-start   <startIndex>] [-length <length>] [-details] [-nofields]   <array object address>

    -或者-

    DA [-start <startIndex>]   [-length <length>] [-detail] [-nofields] <array   object address>

    检查一个数组对象的元素。

    -start 选项指定显示元素的起始索引号。

    -length 选项指定要显示的元素数目。

    -detail 选项按照DumpObjDumpVC格式显示元素的细节。

    -nofields 选项使数组显示不包括字段。仅当指定   -detail 选项时该选项才可用。

    DumpAssembly <Assembly   address>

    显示一个汇编集的有关信息。

    如果存在多个模块,DumpAssembly命令将它们全部列出。

    你可以用DumpDomain命令得到汇编集地址。

    DumpClass <EEClass   address>

    显示与一个类型相关的EEClass结构这些信息。

    DumpClass命令显示静态字段值而不显示非静态字段值。

    使用DumpMTDumpObjName2EE、或Token2EE命令来获取一个EEClass结构地址。

    DumpDomain [<Domain   address>]

    枚举在指定AppDomain对象地址里面装载的每一个Assembly对象。当不带参数调用DumpDomain命令时,它列出一个进程中所有的AppDomain对象。

    DumpHeap [-stat] [-min   <size>][-max <size>] [-thinlock] [-mt   <MethodTable address>] [-type <partial type name>][start   [end]]

    显示关于垃圾收集堆的信息和有关对象的收集统计。

    DumpHeap命令如果在垃圾收集器堆中检测到过多的碎片,它显示一个警告。

    -stat 选项限制输出内容只有统计的类型摘要。

    -min 选项忽略那些尺寸小于size参数的对象,以字节为单位。

    -max 选项忽略那些尺寸大于size参数的对象,以字节为单位。

    -thinlock 选项报告ThinLocks。更多信息请看SyncBlk命令。

    -mt 选项只列出符合所指定MethodTable结构的那些对象。

    -type 选项只列出类型名字子串匹配指定字符串的那些对象。

    参数 start 指定开始列出的地址。

    参数 end 指定停止列出的地址。

    DumpIL [<DynamicMethod   address>] [<DynamicMethodDesc address>] [<MethodDesc address>]

    显示与一个托管方法相关的中间语言(IL)。

    注意,动态IL是发射来的(emitted),不同于从一个汇编集装载的IL。动态IL引用一个托管对象数组中的对象,而不是通过元数据标记引用对象。

    DumpLog [<Filename>]

    把一个内存里的重要日志的内容写入指定文件。如果你没有指定文件名,该命令在当前目录中创建一个名为Stresslog.txt的文件。

    公共语言运行时提供一个内存里的重要日志,帮助你诊断重要失败。日志使你可以不使用锁或I/O就能诊断失败。若要启用重要日志,需要在HKEY_LOCAL_MACHINESOFTWAREMicrosoft.NETFramework下面设置以下注册表项:

    (DWORD) StressLog = 1

    (DWORD) LogFacility = 0xffffffff

    (DWORD) StressLogSize = 65536

    DumpMD <MethodDesc   address>

    显示的信息是在指定地址上的一个MethodDesc结构。

    你可以用IP2MD命令得到一个托管函数的MethodDesc结构地址。

    DumpMT [-MD]   <MethodTable address>

    显示在指定地址上的一个方法表的有关信息。指定 -MD   选项显示列出该对象定义的所有方法。

    每个托管对象包含有一个方法表指针。

    DumpMethodSig <sigaddr>   <moduleaddr>

    显示在指定地址上的一个MethodSig结构的有关信息。

    DumpModule [-mt]   <Module address>

    显示在指定地址上的一个模块的有关信息。-mt 选项显示在该模块中所定义的类型和被该模块引用的类型。

    你可以用DumpDomainDumpAssembly命令检索一个模块的地址。

    DumpObj <object   address>

    -或者-

    DO <object address>

    显示在指定地址上的一个对象的有关信息。DumpObj命令显示字段、EEClass结构信息、方法表和该对象的尺寸。

    你可以用DumpStackObjects命令检索一个对象的地址。

    注意,因为类型CLASS的字段也是对象,所以你可以对它们执行DumpObj命令。

    DumpRuntimeTypes

    显示在垃圾收集器堆中的运行时类型对象,并列出与它们相关的类型名字和方法表。

    DumpStack [-EE]   [top stack [bottom stack]]

    显示一个栈跟踪(回溯)。

    -EE 选项使DumpStack命令只显示托管函数。在x86平台上使用topbottom参数限制所显示的栈框架。

    在x86平台上,DumpStack命令创建一个冗长的栈跟踪。

    在x64和基于IA-64的平台上,DumpStack命令模仿调试器的 K 命令。在x64和基于IA-64的平台上topbottom参数被忽略。

    DumpSig <sigaddr>   <moduleaddr>

    显示在指定地址上的一个Sig结构的有关信息。

    DumpStackObjects [-verify]   [top stack [bottom stack]]

    -或者-

    DSO [-verify] [top   stack [bottom stack]]

    显示在当前栈范围内找到的所有托管对象。

    -verify 选项验证对象字段的每一个非静态CLASS字段。

    带有栈跟踪命令使用DumpStackObject命令,比如 K 命令和CLRStack命令确定局部变量和参数的值。

    DumpVC <MethodTable   address> <Address>

    显示在指定地址上的一个值类的字段信息。

    MethodTable参数使DumpVC命令能够正确地解释字段。值类不以方法表作为它们的第一个字段。

    EEHeap [-gc] [-loader]

    显示被公共语言运行时内部数据结构使用的进程内存的有关信息。

    -gc-loader 选项限制该命令的输出内容为垃圾收集器或者装载器的数据结构。

    对于垃圾收集器,列出在托管堆里每一个节的范围信息。如果某指针是在EEHeap -gc给出的某个节范围内,那么该指针是一个对象指针。

    EEStack [-short] [-EE]

    对进程中所有线程执行DumpStack命令。

    -EE 选项被直接传递给DumpStack命令。-short 参数限制输入内容为以下线程种类:

    1. 已经被锁定的线程。
    2. 为了允许垃圾收集已经被迟延的线程。
    3. 目前处于托管代码中的线程。

    EEVersion

    显示公共语言运行时版本。

    EHInfo [<MethodDesc   address>] [<Code address>]

    显示所指定方法里的异常处理块。这个命令显示子句块(try块)和处理者块(catch块)的代码地址及偏移量。

    FinalizeQueue [-detail]

    显示为终结(finalization)而登记的所有对象。

    -detail 选项显示关于等待清除的任何SyncBlocks的附加信息和等待清除的任何RuntimeCallableWrappers (RCWs) 的额外信息。两个数据结构都是由终结器(finalizer)线程缓存和清除。

    FindAppDomain <Object   address>

    确定在指定地址上的一个对象的应用程序域。

    GCHandles [-perdomain]

    显示在进程中垃圾收集器句柄的统计。

    如果传递-perdomain 选项,则按照应用程序域顺序排列统计。

    使用GCHandles命令查找由垃圾收集器句柄泄漏引起的内存泄漏。例如,由于一个强健的垃圾收集器句柄指向代码的一个大数组成部分,而该句柄没有被释放就丢弃了,所以代码实际上还保留着这个数组,这时就出现一个内存泄漏。

    GCHandleLeaks

    在内存里搜索进程中对那些强健而且有麻烦的垃圾收集器句柄的任何引用,并且显示结果。如果找到某个句柄,GCHandleLeaks命令显示该引用的地址。如果在内存里没有找到某个句柄,这个命令显示一个通知。

    GCInfo <MethodDesc   address><Code address>

    显示数据指示何时寄存器或栈位置包含有托管对象。如果发生垃圾收集,收集器必须知道指向对象的引用的位置,如此它才可以用新的对象指针值更新它们。

    GCRoot [-nostacks]   <Object address>

    显示对在指定地址上的一个对象的引用(或根)信息。

    GCRoot命令检查整个托管堆和在栈以及其他对象里面句柄的句柄表。然后,在每个栈和终结器队列中搜索指向对象的指针。

    这个命令不确定一个栈根是有效的还是已丢弃的。为了确定栈根是否还在使用中,需要用CLRStackU命令反汇编局部变量或参数值所属的框架。

    -nostacks 选项限制只搜索垃圾收集器句柄和终结器队列里的对象(freachable objects)。

    help [<command>]   [<faq>]

    当没有指定参数时显示所有可用命令,或者当指定命令为参数时显示其详细帮助信息。

    faq 参数显示常问问题的答案。

    IP2MD <Code address>

    显示在已经即时编译(JIT)的代码里指定地址上的MethodDesc结构。

    MinidumpMode [0] [1]

    防止在使用一个小转储(minidump)时执行非安全命令。

    传递 0 以禁用这个功能,或传递 1 以启用这个功能。默认地,MinidumpMode把值设置为 0

    .dump /m 命令或者 .dump 命令创建的小转储已经限制为特定的CLR数据,并且让你只可以正确地运行SOS命令的一个子集。有些命令可能因不可预见的错误而失败,因为所必需的内存区域没有被映射或者只有部分被映射。这个选项让你避免对小转储执行非安全命令。

    Name2EE <module   name> <type or method name>

    -或者-

    Name2EE <module   name>!<type or method name>

    显示指定模块中指定类型或方法的MethodTable结构和EEClass结构。

    指定模块必须被装入进程中。

    可以使用MSIL反汇编器 (Ildasm.exe) 浏览模块,以取得适当的类型名字。你也可以传递 * 作为模块名字参数以搜索所有装入的托管模块。模块名字参数也可以是调试器给一个模块的名字,比如mscorlibimage00400000

    这个命令支持Windows调试器句法<module>!<type>。该类型必须被完全限定。

    ObjSize [<Object   address>]

    显示指定对象的尺寸。若不带参数,则ObjSize命令显示在托管线程中找到的全部对象的尺寸,显示进程中全部的垃圾收集器句柄,并求出指向那些句柄的所有对象的尺寸总和。ObjSize命令把父对象全部子对象的尺寸也计算在内。

    PrintException [-nested]   [<Exception object address>]

    -或者-

    PE [-nested]   [<Exception object address>]

    编排格式并显示在指定地址上的任何Exception类派生对象的字段。如果你没有指定一个地址,PrintException命令显示当前线程上最近抛出的异常。

    -nested 选项详细显示嵌套的异常对象。

    你可以使用这个命令编排格式并查看_stackTrace字段,这是一个二元数组。

    ProcInfo [-env] [-time]   [-mem]

    显示针对该进程的环境变量、内核CPU时间和内存使用统计。

    RCWCleanupList   <RCWCleanupList address>

    显示在指定地址上的正等待清除的运行时可调用的包裹器列表。

    SaveModule <Base   address> <Filename>

    把装入在指定地址上的一个内存映像写入指定文件。

    StopOnException [-derived]   [-create | -create2] <Exception> <Pseudo-register   number>

    使调试器当指定异常被抛出时停止,而当其他异常被抛出时则继续运行。

    -derived 选项捕获指定异常及其衍生的每个异常。

    SyncBlk [-all |   <syncblk number>]

    显示指定的SyncBlock结构或者所有的SyncBlock结构。如果你没有传递任何参数,SyncBlk命令显示一个线程所有对象相应的SyncBlock结构。

    一个SyncBlock结构是一个附加信息的容器,不必为每个对象创建它。它能够容纳COM互用数据、散列码、和用于线程-安全操作的锁定信息。

    ThreadPool

    显示托管线程池的有关信息,包括在队列中工作请求的数目、完全端口线程的数目、和计时器数目。

    Token2EE <module name>   <token>

    把指定模块中指定的元数据标记转换成一个MethodTable结构或者MethodDesc结构。

    你也可以把 * 作为模块名字参数,以使在每个被载入的托管模块中找出该标记的映射目标。模块名字参数也可以是调试器给一个模块的名字,比如 mscorlib image00400000

    Threads [-live] [-special]

    显示进程中所有的托管线程。

    Threads命令显示 调试器简写ID号、公共语言运行时线程ID号、和正在操作中的系统线程ID号。此外,Threads命令显示 一个Domain栏指示线程运行所处在的应用程序域、一个APT栏显示COM单元的模式、和一个Exception栏显示线程最近抛出的异常。

    -live 选项显示与某个活线程有关联的那些线程。

    -special 选项显示CLR创建的所有特别线程。特别线程包括(并发GC和服务器GC中的)垃圾收集(GC)线程、调试器助手线程、Finalizer线程、AppDomain卸载线程、和线程池计时器线程。

    TraverseHeap [-xml]   <filename>

    遵照CLR简档器隐含的格式把堆信息写入到指定文件。-xml选项使TraverseHeap命令把该文件格式化为XML。

    你能够从: http://www.microsoft.com/downloads/details.aspx?familyid=86ce6052-d7f4-4aeb-9b7a-94635beebdda   下载CLR简档器。

    U [-gcinfo] [-ehinfo]   <MethodDesc address> | <Code address>

    通过指定一个指向某个方法MethodDesc结构的指针或者指定其方法体里面的一个代码地址,显示一个托管方法有注释的反汇编。U命令显示整个方法,从开始到完成,并在注释里把元数据标记转换为名字。

    -gcinfo 选项使U命令显示这个方法使用的GCInfo结构。

    -ehinfo 选项显示这个方法的异常信息。你也可以用EHInfo命令来获取该信息。

    VerifyHeap

    检查垃圾收集器堆的崩溃标志,显示发现的任何错误。

    堆崩溃能够由不正确地构成的平台援用(platform invoke)调用引起。

    VMMap

    横跨虚拟地址空间,显示加诸每区域的保护类型。

    VMStat

    按照加诸内存的保护类型(自由的free、保留的reserved、约束的committed、私有的private、映射的mapped、映像image)顺序,提供虚拟地址空间的概览。TOTAL栏显示AVERAGE栏乘以BLK   COUNT栏的结果。

     注:个人总结整理,如有指教问题请liudaoyu@outlook.com 谢谢!

  • 相关阅读:
    C语言与数据库操作入门(Win版)
    用C语言操作MySQL数据库,进行连接、插入、修改、删除等操作
    c语言连接mysql数据库的实现方法
    linux shell 之 crontab(定时任务)详解
    Centos7下面配置静态IP
    安装php
    Deep Learning
    Deep Learning
    Deep Learning
    数据分析
  • 原文地址:https://www.cnblogs.com/daoyuly/p/3570037.html
Copyright © 2020-2023  润新知