windbg除錯系列教程:sos擴充套件的介紹和使用

志存高遠,腳踏實地發表於2022-02-22

SOS是什麼?

直觀來說,sos就是一個程式集檔案。這個程式集的作用就是讓我們在使用windbg分析.net程式時,更加方便快捷。通過sos,我們可以清晰的檢視CLR執行時的各類資訊,輔助我們去理解託管記憶體的狀態和含義。

這個程式集是隨.NET Framework一起安裝的,一般不需要單獨安裝。在我本機自動安裝的位置如下:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.dll

 

如何載入和使用

一般情況,使用windbg自帶的命令【.loadby sos clr】即可自動載入,使用【.chain】檢視載入是否成功。

0:098> .loadby sos clr
0:098> .chain
Extension DLL search Path:
    ....省略....
Extension DLL chain:
    ....省略....
    C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll: image 4.8.9014.0, API 1.0.0, built Tue Oct 12 08:17:44 2021
        [path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll]
    ....省略....

此擴充套件提供的所有命令格式均為:![command] [options],下面就根據命令作用分類,講解重要且常用的命令。

檢視執行緒的命令

  1. Threads命令
    • 作用:輸出全部託管執行緒資訊
    • Threads [-live] [-special]
      • 預設輸出常規的工作執行緒資訊
      • -live 只輸出存活的執行緒
      • -special 只輸出特殊執行緒資訊,包含:GC執行緒、debugger輔助執行緒、finalizer執行緒、AppDomain unload執行緒、執行緒池定時器執行緒
    • 輸出示例和解讀:
    • 檢視程式碼
      0:015> !Threads
      ThreadCount:      4
      UnstartedThread:  0
      BackgroundThread: 3
      PendingThread:    0
      DeadThread:       0
      Hosted Runtime:   no
                                                                                                              Lock  
             ID OSID ThreadOBJ           State GC Mode     GC Alloc Context                  Domain           Count Apt Exception
         0    1 5320 0000024cdf5efd80    26020 Preemptive  0000024CE14ECC50:0000024CE14EDC30 0000024cdf5c4cf0 0     STA 
         5    2 7c74 0000024cdf618df0    2b220 Preemptive  0000000000000000:0000000000000000 0000024cdf5c4cf0 0     MTA (Finalizer) 
        15    3 5844 0000024cfedca6a0  3029220 Preemptive  0000024CE14CA048:0000024CE14CBC30 0000024cdf5c4cf0 0     MTA (Threadpool Worker) 
        16    4 7dc0 0000024cfed99a20  1029220 Preemptive  0000024CE14CBF38:0000024CE14CDC30 0000024cdf5c4cf0 0     MTA (Threadpool Worker)
      
            
      0:098> !Threads -special
                      OSID Special thread type
              1 27d3c DbgHelper 
              2 22954 GC 
              3 2b168 GC 
              4 c478 GC 
              5 13778 GC 
              6 62ec GC 
              7 2dd1c GC 
              8 ec60 GC 
              9 138b8 GC 
             10 e988 Finalizer 
             11 9850 ProfilingAPIAttach 
             16 180c Timer 
             17 24960 ThreadpoolWorker 
             18 e70c ThreadpoolWorker 
             20 29e94 GC 
             21 2abdc GC 
             22 2d760 GC 
             23 22ad8 GC 
             24 2d288 GC 
             25 9750 GC 
             26 52e8 GC 
             27 2b9a4 GC 
             29 18340 Wait 
             ....省略....
    • 空列 ID OSID:前三列分別是windbg自定義的執行緒序列、CLR執行緒ID、OS執行緒ID。XXXX代表執行緒已Dead。
    • ThreadOBJ是執行緒的物件地址
    • Domain列代表當前執行緒所在的AppDomain,Lock Count列代表當前執行緒持有的鎖數量,
    • APT列代表執行緒的COM模式,有MTA、Ukn等值,能區分執行緒型別(Finalizer\Threadpool Worker\Threadpool Completion Port等)
    • Exception列表示對應執行緒最新的異常物件。
  2. ThreadState命令
    • 作用:檢視執行緒狀態。
    • ThreadState < State value field >,引數就是上個命令輸出的state值。
    • 輸出示例和解讀:
    • 0:015> !ThreadState 1029220
          Legal to Join
          Background
          CLR Owns
          In Multi Threaded Apartment
          Fully initialized
          Thread Pool Worker Thread
      
    • 表明這是後臺執行緒、屬於CLR、初始化完成、是執行緒池工作執行緒。
  3.  ThreadPool命令
    • 作用:檢視執行緒池資訊。此命令沒有額外的控制選項。
    • 輸出示例和解讀:
    • 0:001> !threadpool CPU utilization: 32% Worker Thread: Total: 183 Running: 154 Idle: 29 MaxLimit: 1000 MinLimit: 100 Work Request in Queue: 0 -------------------------------------- Number of Timers: 1 -------------------------------------- Completion Port Thread:Total: 10 Free: 6 MaxFree: 16 CurrentLimit: 6 MaxLimit: 200 MinLimit: 20
    • 各項資訊比較清楚,按照需要檢視即可。

檢視堆疊類的命令

  1. clrstack命令:
    • 作用:檢視當前執行緒的託管堆疊
    • CLRStack [-a] [-l] [-p] [-n]
      • -p:輸出內容包含堆疊中的方法入參
      • -l:輸出內容包含堆疊中的方法的區域性變數
      • -a:等效同時使用-p和-l
      • -n:輸出內容不包括原始碼檔案資訊和行號。
    • 輸出示例和解讀:
    • 檢視程式碼
      0:015> !clrstack -n -a
      OS Thread Id: 0x759c (15)
              Child SP               IP Call Site
      0000005c65ffef48 00007ffc73b82f14 [HelperMethodFrame: 0000005c65ffef48] System.Threading.Thread.SleepInternal(Int32)
      0000005c65fff040 00007ffc5988b78b System.Threading.Thread.Sleep(Int32)
          PARAMETERS:
              millisecondsTimeout = <no data>
      
      0000005c65fff070 00007ffbfc3c946b Tccc.WindbgDemoAPP.MainWindow+c.b__22_0(System.Object)
          PARAMETERS:
              this (0x0000005c65fff0a0) = 0x0000023f431ffd68
              a (0x0000005c65fff0a8) = 0x0000000000000000
      
      0000005c65fff0a0 00007ffc59853480 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
          PARAMETERS:
              executionContext = <no data>
              callback = <no data>
              state = <no data>
              preserveSyncCtx = <no data>
          LOCALS:
              <no data>
              <no data>
              <no data>
      
      0000005c65fff170 00007ffc59853305 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
          PARAMETERS:
              executionContext = <no data>
              callback = <no data>
              state = <no data>
              preserveSyncCtx = <no data>
      
      0000005c65fff1a0 00007ffc5987a506 System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
          PARAMETERS:
              this = <no data>
          LOCALS:
              <no data>
      
      0000005c65fff1e0 00007ffc59879746 System.Threading.ThreadPoolWorkQueue.Dispatch()
          LOCALS:
              0x0000005c65fff230 = 0x0000023f431ffdc0
              0x0000005c65fff25c = 0x000000002019e530
              0x0000005c65fff258 = 0x0000000000000001
              <no data>
              0x0000005c65fff228 = 0x0000023f43201cb0
              <no data>
              0x0000005c65fff244 = 0x0000000000000000
              <no data>
              <no data>
      
      0000005c65fff678 00007ffc5b927873 [DebuggerU2MCatchHandlerFrame: 0000005c65fff678]
    • IP列代表當前方法的程式碼地址入口,通過!U命令可以檢視IL程式碼和彙編程式碼。Call Site列就是堆疊方法資訊。
    • PARAMETERS和LOCALS分別代表對應方法的入參和區域性變數。其中入參可以正常顯示名稱,但是區域性變數沒有實際變數名稱,而是通過變數地址來表示:<local address= <value>。
  2. dumpstack命令
    • 作用:檢視執行緒的完整堆疊資訊(包含託管、非託管)
    • DumpStack [-EE] [-n] [top stack [bottom stack]]
      • -ee:只顯示託管程式碼的堆疊資訊
      • -n:同上,輸出資訊遮蔽掉原始碼檔案資訊和行號
    • 輸出示例和解讀:
    • 檢視程式碼
      0:015> !dumpstack -ee
      OS Thread Id: 0x759c (15)
      Current frame: 
      Child-SP         RetAddr          Caller, Callee
      0000005c65fff030 00007ffc5988b78b (MethodDesc 00007ffc594b9090 +0xb System.Threading.Thread.Sleep(Int32))
      0000005c65fff060 00007ffbfc3c946b (MethodDesc 00007ffbfc45eb10 +0x2b Tccc.WindbgDemoAPP.MainWindow+<>c.<sleepBtn_Click>b__22_0(System.Object))
      0000005c65fff090 00007ffc59853480 (MethodDesc 00007ffc592f8a18 +0x170 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean))
      0000005c65fff160 00007ffc59853305 (MethodDesc 00007ffc594c5248 +0x15 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean))
      0000005c65fff190 00007ffc5987a506 (MethodDesc 00007ffc594e3570 +0x76 System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem())
      0000005c65fff1d0 00007ffc59879746 (MethodDesc 00007ffc5965fbc0 +0x156 System.Threading.ThreadPoolWorkQueue.Dispatch())
    • RetAddr列代表當前方法的程式碼地址入口,同上的IP列。Caller, Callee列包含方法MethodDesc值和方法簽名資訊。
  3. eestack命令
    • 作用:檢視所有執行緒的堆疊,完全等價於每個執行緒執行dumpstack命令
    • EEStack [-short] [-EE]
      • -EE同上
      • -short:只輸出符合條件的執行緒堆疊:持有鎖的執行緒、GC掛起的執行緒、正在執行託管程式碼的執行緒。
    • 輸出示例和解讀:同上,略。
  4. dso命令
    • 作用:檢視當前執行緒的全部託管物件。
    • DSO [-verify] [top stack [bottom stack]]
    • 輸出示例和解讀:
    • 0:015> !dso 
      OS Thread Id: 0x759c (15)
      RSP/REG          Object           Name
      0000005C65FFEF58 0000023f43200628 System.Threading.QueueUserWorkItemCallback
      0000005C65FFEF78 0000023f43200690 System.Threading.ExecutionContext
      0000005C65FFEF80 0000023f43200650 System.Threading.ContextCallback
      0000005C65FFEF98 0000023f43200650 System.Threading.ContextCallback
      0000005C65FFEFC0 0000023f43201fe8 System.Threading.Thread
      0000005C65FFF000 0000023f43200690 System.Threading.ExecutionContext
      0000005C65FFF020 0000023f43201fe8 System.Threading.Thread
      0000005C65FFF028 0000023f43200628 System.Threading.QueueUserWorkItemCallback
      0000005C65FFF048 0000023f43200650 System.Threading.ContextCallback
      0000005C65FFF050 0000023f43200690 System.Threading.ExecutionContext
      0000005C65FFF060 0000023f43200690 System.Threading.ExecutionContext
      0000005C65FFF088 0000023f43200628 System.Threading.QueueUserWorkItemCallback
      0000005C65FFF0A0 0000023f431ffd68 Tccc.WindbgDemoAPP.MainWindow+<>c
      0000005C65FFF0E0 0000023f43201fe8 System.Threading.Thread
      0000005C65FFF140 0000023f43200628 System.Threading.QueueUserWorkItemCallback
      0000005C65FFF148 0000023f43200690 System.Threading.ExecutionContext
      0000005C65FFF1E0 0000023f43200628 System.Threading.QueueUserWorkItemCallback
      0000005C65FFF228 0000023f43201cb0 System.Threading.ThreadPoolWorkQueueThreadLocals
      0000005C65FFF230 0000023f431ffdc0 System.Threading.ThreadPoolWorkQueue
      0000005C65FFF250 0000023f43200628 System.Threading.QueueUserWorkItemCallback
      
    • Object列是物件地址,Name列時物件型別名稱。

檢視鎖的命令

  1. syncblk命令
    • 作用:檢視程式中同步塊鎖的持有情況和等待情況。常用於分析死鎖問題。
    • SyncBlk [-all | <syncblk number>]
      • 預設輸出被執行緒持有的鎖資訊
      • -all:輸出全部的SyncBlock物件資訊
      • syncblk number:指定鎖編號
    • 輸出示例和解讀:
    • 0:098> !syncblk
      Index SyncBlock MonitorHeld Recursion Owning Thread Info  SyncBlock Owner
        510 000002bb0513d4a8           79         1 000002bb073568c0 f9e8 177   000002be7520adb0 System.Object
        530 000002bb0513a1f8          219         1 000002bb06a17770 26bdc 112   000002bd74f07d30 System.Object
        567 000002bb0513e148            5         1 000002bb06ce6f40 24ce0 113   000002be74f320b8 System.Object
       1343 000002bb0513c2b8            7         1 000002bb06a17770 26bdc 112   000002bd7515b158 ServiceStack.Redis.RedisSentinelWorker
      -----------------------------
      Total           1369
      CCW             3
      RCW             2
      ComClassFactory 0
      Free            507
      
    • Index列是編號,SyncBlock列是鎖地址,MonitorHeld是等待計數器,Recursion代表持有此鎖的執行緒數量,Owning Thread Info這3列代表持有鎖的執行緒資訊,SyncBlock Owner代表鎖物件地址和型別。
    • MonitorHeld值的含義:當一個執行緒持有了鎖的時候 MonitorHeld+1 ,當一個執行緒在等待鎖的時候 MonitorHeld+2。因此示例中510號鎖的等待執行緒數量=(79-1)/2=39。

檢視程式資訊、記憶體分佈的命令

  1. EEVersion命令
    • 作用:檢視CLR版本資訊
    • 輸出示例和解讀:
    • 0:001> !eeversion
      4.8.4380.0 free
      Server mode with 8 gc heaps
      SOS Version: 4.8.4380.0 retail build
      
  2. DumpDomain命令
    • 作用:檢視應用程式域資訊
    • DumpDomain [<domain address>],引數為指定程式域的地址,不帶引數輸出全部程式域資訊。
    • 輸出示例和解讀:
    • 檢視程式碼
      0:015> !dumpdomain
      --------------------------------------
      System Domain:      00007ffc5c3006e0
      LowFrequencyHeap:   00007ffc5c300c58
      HighFrequencyHeap:  00007ffc5c300ce8
      StubHeap:           00007ffc5c300d78
      Stage:              OPEN
      Name:               None
      --------------------------------------
      Shared Domain:      00007ffc5c300110
      LowFrequencyHeap:   00007ffc5c300c58
      HighFrequencyHeap:  00007ffc5c300ce8
      StubHeap:           00007ffc5c300d78
      Stage:              OPEN
      Name:               None
      Assembly:           0000024cdf62db80 [C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
      ClassLoader:        0000024cdf62dca0
        Module Name
      00007ffc592f1000            C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
      
      --------------------------------------
      Domain 1:           0000024cdf5c4cf0
      LowFrequencyHeap:   0000024cdf5c54e8
      HighFrequencyHeap:  0000024cdf5c5578
      StubHeap:           0000024cdf5c5608
      Stage:              OPEN
      SecurityDescriptor: 0000024cdf5c7300
      Name:               Tccc.WindbgDemoAPP.exe
      Assembly:           0000024cdf62db80 [C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll]
      ClassLoader:        0000024cdf62dca0
      SecurityDescriptor: 0000024cdf6317c0
        Module Name
      00007ffc592f1000            C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
      
      Assembly:           0000024cdf640bb0 [D:\50LearningSln\Tccc\Tccc.WindbgDemoAPP\bin\x64\Debug\Tccc.WindbgDemoAPP.exe]
      ClassLoader:        0000024cdf640cd0
      SecurityDescriptor: 0000024cdf640ac0
        Module Name
      00007ffbfc2a4140            D:\50LearningSln\Tccc\Tccc.WindbgDemoAPP\bin\x64\Debug\Tccc.WindbgDemoAPP.exe
    • 輸出內容包含系統程式域、共享程式域、Domain1等。同時,程式域中載入的程式集資訊也列印出來。這裡的程式集路徑可以準確判斷程式載入的檔案位置,非常有用。
  3.  eeheap命令
    • 作用:檢視程式內的CLR記憶體分佈。
    • EEHeap [-gc] [-loader],預設輸出全部記憶體分佈資訊。
      • -gc只輸出gc堆和大物件堆
      • -loader只輸出載入器相關的記憶體分佈
    • 輸出示例和解讀:
    • 檢視程式碼
      0:015> !eeheap
      Loader Heap:
      --------------------------------------
      System Domain:     00007ffc5c3006e0
      LowFrequencyHeap:  00007ffbfc290000(3000:3000) Size: 0x3000 (12288) bytes.
      HighFrequencyHeap: 00007ffbfc294000(9000:3000) Size: 0x3000 (12288) bytes.
      StubHeap:          00007ffbfc29d000(3000:3000) 00007ffbfc450000(10000:1000) Size: 0x4000 (16384) bytes.
      Virtual Call Stub Heap:
        IndcellHeap:     00007ffbfc340000(6000:1000) Size: 0x1000 (4096) bytes.
        LookupHeap:      00007ffbfc34c000(4000:1000) Size: 0x1000 (4096) bytes.
        ResolveHeap:     00007ffbfc376000(3a000:2000) Size: 0x2000 (8192) bytes.
        DispatchHeap:    00007ffbfc350000(26000:1000) Size: 0x1000 (4096) bytes.
        CacheEntryHeap:  00007ffbfc346000(6000:1000) Size: 0x1000 (4096) bytes.
      Total size:        Size: 0x10000 (65536) bytes.
      --------------------------------------
      Shared Domain:     00007ffc5c300110
      LowFrequencyHeap:  00007ffbfc290000(3000:3000) Size: 0x3000 (12288) bytes.
      HighFrequencyHeap: 00007ffbfc294000(9000:3000) Size: 0x3000 (12288) bytes.
      StubHeap:          00007ffbfc29d000(3000:3000) 00007ffbfc450000(10000:1000) Size: 0x4000 (16384) bytes.
      Virtual Call Stub Heap:
        IndcellHeap:     00007ffbfc340000(6000:1000) Size: 0x1000 (4096) bytes.
        LookupHeap:      00007ffbfc34c000(4000:1000) Size: 0x1000 (4096) bytes.
        ResolveHeap:     00007ffbfc376000(3a000:2000) Size: 0x2000 (8192) bytes.
        DispatchHeap:    00007ffbfc350000(26000:1000) Size: 0x1000 (4096) bytes.
        CacheEntryHeap:  00007ffbfc346000(6000:1000) Size: 0x1000 (4096) bytes.
      Total size:        Size: 0x10000 (65536) bytes.
      --------------------------------------
      Domain 1:          0000024cdf5c4cf0
      LowFrequencyHeap:  00007ffbfc2a0000(3000:3000) 00007ffbfc430000(10000:d000) Size: 0x10000 (65536) bytes.
      HighFrequencyHeap: 00007ffbfc2a3000(a000:9000) 00007ffbfc440000(10000:f000) Size: 0x18000 (98304) bytes total, 0x1000 (4096) bytes wasted.
      StubHeap:          00007ffbfc2ad000(3000:1000) Size: 0x1000 (4096) bytes.
      Virtual Call Stub Heap:
        IndcellHeap:     00007ffbfc2b0000(4000:1000) Size: 0x1000 (4096) bytes.
        LookupHeap:      00007ffbfc2bb000(2000:1000) Size: 0x1000 (4096) bytes.
        ResolveHeap:     00007ffbfc2ec000(54000:8000) Size: 0x8000 (32768) bytes.
        DispatchHeap:    00007ffbfc2bd000(2f000:3000) Size: 0x3000 (12288) bytes.
        CacheEntryHeap:  00007ffbfc2b4000(7000:1000) Size: 0x1000 (4096) bytes.
      Total size:        Size: 0x37000 (225280) bytes total, 0x1000 (4096) bytes wasted.
      --------------------------------------
      Jit code heap:
      LoaderCodeHeap:    0000000000000000(0:0) Size: 0x0 (0) bytes.
      Total size:        Size: 0x0 (0) bytes.
      --------------------------------------
      Module Thunk heaps:
      Module 00007ffc592f1000: Size: 0x0 (0) bytes.
      Module 00007ffbfc2a4140: Size: 0x0 (0) bytes.
      Module 00007ffc192a1000: Size: 0x0 (0) bytes.
      Module 00007ffc1aa31000: Size: 0x0 (0) bytes.
      Module 00007ffc54e51000: Size: 0x0 (0) bytes.
      Module 00007ffc18d91000: Size: 0x0 (0) bytes.
      Module 00007ffc4e2d1000: Size: 0x0 (0) bytes.
      Module 00007ffc36e51000: Size: 0x0 (0) bytes.
      Module 00007ffc4c0d1000: Size: 0x0 (0) bytes.
      Module 00007ffc4b821000: Size: 0x0 (0) bytes.
      Module 00007ffc17241000: Size: 0x0 (0) bytes.
      Module 00007ffbfc44bce8: Size: 0x0 (0) bytes.
      Module 00007ffbfc44c6a8: Size: 0x0 (0) bytes.
      Module 00007ffbfc44d2b8: Size: 0x0 (0) bytes.
      Module 00007ffc13541000: Size: 0x0 (0) bytes.
      Module 00007ffc22ef1000: Size: 0x0 (0) bytes.
      Total size:              Size: 0x0 (0) bytes.
      --------------------------------------
      Module Lookup Table heaps:
      Module 00007ffc592f1000: Size: 0x0 (0) bytes.
      Module 00007ffbfc2a4140: Size: 0x0 (0) bytes.
      Module 00007ffc192a1000: Size: 0x0 (0) bytes.
      Module 00007ffc1aa31000: Size: 0x0 (0) bytes.
      Module 00007ffc54e51000: Size: 0x0 (0) bytes.
      Module 00007ffc18d91000: Size: 0x0 (0) bytes.
      Module 00007ffc4e2d1000: Size: 0x0 (0) bytes.
      Module 00007ffc36e51000: Size: 0x0 (0) bytes.
      Module 00007ffc4c0d1000: Size: 0x0 (0) bytes.
      Module 00007ffc4b821000: Size: 0x0 (0) bytes.
      Module 00007ffc17241000: Size: 0x0 (0) bytes.
      Module 00007ffbfc44bce8: Size: 0x0 (0) bytes.
      Module 00007ffbfc44c6a8: Size: 0x0 (0) bytes.
      Module 00007ffbfc44d2b8: Size: 0x0 (0) bytes.
      Module 00007ffc13541000: Size: 0x0 (0) bytes.
      Module 00007ffc22ef1000: Size: 0x0 (0) bytes.
      Total size:              Size: 0x0 (0) bytes.
      --------------------------------------
      Total LoaderHeap size:   Size: 0x57000 (356352) bytes total, 0x1000 (4096) bytes wasted.
      =======================================
      Number of GC Heaps: 1
      generation 0 starts at 0x0000024ce1407c30
      generation 1 starts at 0x0000024ce12a1018
      generation 2 starts at 0x0000024ce12a1000
      ephemeral segment allocation context: none
               segment             begin         allocated              size
      0000024ce12a0000  0000024ce12a1000  0000024ce14edc48  0x24cc48(2411592)
      Large object heap starts at 0x0000024cf12a1000
               segment             begin         allocated              size
      0000024cf12a0000  0000024cf12a1000  0000024cf12c31f0  0x221f0(139760)
      Total Size:              Size: 0x26ee38 (2551352) bytes.
      ------------------------------
      GC Heap Size:            Size: 0x26ee38 (2551352) bytes.
      
    • 輸出內容包含各個程式域記憶體資訊、JIT堆、GC堆、載入器堆等地址資訊。
  4. dumpheap命令
    • 作用:檢視記憶體中的物件資訊,非常有用。
    • DumpHeap [-stat]  [-mt <MethodTable address>] [-type <partial type name>]
      • 預設輸出全部的物件明細,資料量大,一般都會帶引數限制輸出大小。
      • -stat:按照物件的型別,彙總輸出,最常用的選項。
      • -mt <MethodTable address>:根據MethodTable地址過濾物件。
      • -type <partial type name>:根據型別名稱過濾物件,區分大小寫,不需要提供完整型別。
    • 輸出示例和解讀:
    • 0:001> !dumpheap -stat -mt 00007ffbee0abd78
      Statistics:
                    MT    Count    TotalSize Class Name
      00007ffbee0abd78    34150      1366000 System.Net.SocketAddress
      Total 34150 objects
      
      
      
      0:001> !dumpheap -stat -type Net.SocketAddress
      Statistics:
                    MT    Count    TotalSize Class Name
      00007ffbee0abd78    34150      1366000 System.Net.SocketAddress
      Total 34150 objects
  5. dumpobj命令
    • 作用:檢視物件資訊
    • DumpObj <object address>
    • 輸出示例和解讀:
    • 檢視程式碼
      
      0:015> !DumpObj /d 0000024ce12acc98
      Name:        System.Threading.Thread
      MethodTable: 00007ffc59304e08
      EEClass:     00007ffc59481748
      Size:        96(0x60) bytes
      File:        C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
      Fields:
                    MT    Field   Offset                 Type VT     Attr            Value Name
      00007ffc5938ea98  400192d        8 ....Contexts.Context  0 instance 0000000000000000 m_Context
      00007ffc5930c3a0  400192e       10 ....ExecutionContext  0 instance 0000024ce12d30a0 m_ExecutionContext
      00007ffc59303db8  400192f       18        System.String  0 instance 0000000000000000 m_Name
      00007ffc59306628  4001930       20      System.Delegate  0 instance 0000000000000000 m_Delegate
      00007ffc59308090  4001931       28 ...ation.CultureInfo  0 instance 0000000000000000 m_CurrentCulture
      00007ffc59308090  4001932       30 ...ation.CultureInfo  0 instance 0000000000000000 m_CurrentUICulture
      00007ffc593041d0  4001933       38        System.Object  0 instance 0000000000000000 m_ThreadStartArg
      00007ffc5930d260  4001934       40        System.IntPtr  1 instance      24cdf5efd80 DONT_USE_InternalThread
      00007ffc59306ad8  4001935       48         System.Int32  1 instance                2 m_Priority
      00007ffc59306ad8  4001936       4c         System.Int32  1 instance                1 m_ManagedThreadId
      00007ffc5930a420  4001937       50       System.Boolean  1 instance                0 m_ExecutionContextBelongsToOuterScope
      00007ffc59326f88  4001938      e30 ...LocalDataStoreMgr  0   shared           static s_LocalDataStoreMgr
                                       >> Domain:Value  0000024cdf5c4cf0:NotInit  <<
      00007ffc5a588408  400193a      e38 ...eInfo, mscorlib]]  0   shared           static s_asyncLocalCurrentCulture
                                       >> Domain:Value  0000024cdf5c4cf0:NotInit  <<
      00007ffc5a588408  400193b      e40 ...eInfo, mscorlib]]  0   shared           static s_asyncLocalCurrentUICulture
                                       >> Domain:Value  0000024cdf5c4cf0:NotInit  <<
      00007ffc59328a18  4001939       18 ...alDataStoreHolder  0   shared         TLstatic s_LocalDataStore
          >> Thread:Value <<
      00007ffc59306ad8  400193c      d10         System.Int32  1   shared         TLstatic t_currentProcessorIdCache
          >> Thread:Value <<
      
    • 其中Attr列的instance代表當前行是例項欄位,Value是Field的值,Name是當前Field的名稱。

檢視異常的命令

  1. pe命令
    • 作用:檢視當前執行緒的異常。
    • 輸出示例和解讀:
    • 檢視程式碼
      
      0:098> !pe
      Exception object: 000002bbf5127940
      Exception type:   ServiceStack.Redis.RedisException
      Message:          Host:10.201.107.xxx,Port:26379 Exceeded timeout of 00:00:03
      InnerException:   System.Net.Sockets.SocketException, Use !PrintException 000002bef5278f08 to see more.
      StackTrace (generated):
          SP               IP               Function
          000000D8D77FC260 00007FFB92F54063 UNKNOWN!ServiceStack.Redis.RedisNativeClient.SendReceive[[System.__Canon, mscorlib]](Byte[][], System.Func`1<System.__Canon>, System.Action`1<System.Func`1<System.__Canon>>, Boolean)+0x2b3
          000000D8D77FE510 00007FFB92F596C4 UNKNOWN!ServiceStack.Redis.RedisNativeClient.SendExpectMultiData(Byte[][])+0xd4
      ...省略....
          000000D8D77FE8A0 00007FFB92F5D681 UNKNOWN!ServiceStack.Redis.RedisSubscription.SubscribeToChannelsMatching(System.String[])+0x51
          000000D8D77FE8D0 00007FFB92F5CFC5 UNKNOWN!ServiceStack.Redis.RedisPubSubServer.RunLoop()+0x1d5
      
      StackTraceString: <none>
      HResult: 80131500
      
    • 輸出內容包含了完整的異常資訊,比如異常物件地址、Message內容、異常堆疊,甚至連InnerException也有提示。

總結

本文不僅是教程,也是一份手冊。SOS提供了非常多的命令,需要逐步摸索實踐,這些命令只有親自實踐後才能夠真正掌握。

參考資料

SOS.dll (SOS Debugging Extension) - .NET Framework | Microsoft Docs

相關文章