Windbg使用簡明指南


第一章 准備

1.1.    環境配置

 

_NT_DEBUGGER_EXTENSION_PATH=C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727

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

 

Path add:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727

C:\Program Files\Debugging 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:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.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:\temp\a.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 Files\Debugging 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:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.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:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\

 

Temporary ASP.NET   Files\buggybits\b27906cc\f5f91899\App_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 clr10\sos

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_MACHINE\SOFTWARE\Microsoft\.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 謝謝!

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM