利用SOS分析调试托管代码--(2)

  

  • 查看线程和同步块
  • 1.查看托管线程
      Threads命令显示进程中的所有托管线程及统计信息。-special选项显示由 CLR 创建的所有特殊线程,包括GC线程、调试器帮助程序线程、终结器线程、 AppDomain卸载线程和线程池计时器线程。
      
    Threads
    !Threads -special
    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
    11820 1 2e2c 003e7ee8 8a028 Enabled 01b0ba14:01b0c004 003e16b0 1 MTA
    10364 2 287c 003e99a0 b228 Enabled 00000000:00000000 003e16b0 0 MTA (Finalizer)

    OSID Special thread type
    10364 287c Finalizer
       
        可以看到当前有2个线程,1个属于后台线程。线程2是终结器线程。我们还可以看到线程1存在一个锁。
      
      2.查看线程状态
        线程State只是一个值,我们需要得到具体的描述,可以利用ThreadState命令显示线程的状态。value参数为Threads输出中的State字段的值。
      我们查看线程1的状态。
     
    ThreadState
    !ThreadState 8a028
    Debug Suspend Pending
    Legal to Join
    CoInitialized
    In Multi Threaded Apartment
    Sync Suspended
     
    3.查询线程同步块
      线程同步块结构是一个容器,用于存放无需为每个对象创建的额外信息。比如COM互操作数据、哈希代码和用于线程安全操作的锁定信息。
      我们可以用syncblk命令查询所有的线程同步块。
     
    SyncBlk
    !SyncBlk
    Index SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner
    1 0043f9ac 1 1 003e7ee8 2e2c11820 01b0b22c Wuhong.SOSTest.Complex
    -----------------------------
    Total
    1
    CCW
    0
    RCW
    0
    ComClassFactory
    0
    Free
    0
     
      可以看到有线程1的类型为Wuhong.SOSTest.Complex的对象上拥有1个同步块。
     
  • 查看GC
  • 1.查看托管堆统计
      HeapStat命令显示每个堆的生成大小及每个堆上各生成的可用空间总量。-inclUnrooted选项包括有关不再为根的垃圾回收集合堆中的托管对象的信息。
       
    HeapStat
    !HeapStat -inclUnrooted
    Heap Gen0 Gen1 Gen2 LOH
    Heap0
    45048 12 12 8784

    Free
    space: Percentage
    Heap0
    12 0 0 64SOH: 0% LOH: 0%

    Unrooted
    objects: Percentage
    Heap0
    11328 0 0 0SOH: 25% LOH: 0%
      
      2.查看GC句柄
        利用GCHandles命令可以显示进程中的垃圾回收器句柄的统计信息。
       
    GCHandles
    !GCHandles
    GC Handle
    Statistics:
    Strong
    Handles: 10
    Pinned Handles: 4
    Async
    Pinned Handles: 0
    Ref Count
    Handles: 0
    Weak Long
    Handles: 0
    Weak Short
    Handles: 0
    Other
    Handles: 0
    Statistics:
    MT Count TotalSize
    Class Name
    605ff5e8
    1 12 System.Object
    60601b18
    1 28 System.SharedStatics
    60603670 1 36 System.Security.PermissionSet
    605fffcc
    1 48 System.Threading.Thread
    605ffde8
    1 84 System.ExecutionEngineException
    605ffd9c
    1 84 System.StackOverflowException
    605ffd50
    1 84 System.OutOfMemoryException
    605ffc0c
    1 84 System.Exception
    60600ec8
    1 112 System.AppDomain
    605ffe34
    2 168 System.Threading.ThreadAbortException
    605b6c28
    3 8720 System.Object[]
    Total
    14 objects
      
        可以看到进程中一共有4个固定句柄和10个强类型句柄。
      
      3.查看终结器队列
        利用FinalizeQueue命令,可以显示所有已进行终结注册的对象。-allReady 选项显示所有准备终止的对象,无论它们已被垃圾回收标记成这样,还是将被下一个垃圾回收标记。
      
    FinalizeQueue
    !FinalizeQueue
    SyncBlocks to
    be cleaned up: 0
    MTA Interfaces to
    be released: 0
    STA Interfaces to
    be released: 0
    ----------------------------------
    generation
    0 has 3 finalizable objects (00428bb0->00428bbc)
    generation
    1 has 0 finalizable objects (00428bb0->00428bb0)
    generation
    2 has 0 finalizable objects (00428bb0->00428bb0)
    Ready for finalization
    0 objects (00428bbc->00428bbc)
    Statistics for all finalizable objects (including all objects ready for finalization):
    MT Count TotalSize
    Class Name
    605ff4d0
    1 20 Microsoft.Win32.SafeHandles.SafePEFileHandle
    60605efc
    1 44 System.Threading.ReaderWriterLock
    605fffcc
    1 48 System.Threading.Thread
    Total
    3 objects
     
    4.查询对象的根
      利用GCRoot可以显示有关对指定地址处的对象的引用(或根)的信息。搜寻范围是整个托管堆和句柄表,同时还搜索终结器队列。这个命令可以用来确认对象为什么没有被垃圾收集。
      比如我们想查看DumpObj小节中类型为Wuhong.SOSTest.Complex的对象的根。
     
    GCRoot
    !GCRoot 0x01b0b22c
    Note: Roots found on stacks may be false positives. Run "!help gcroot" for
    more info.
    Scan Thread
    11820 OSTHread 2e2c
    ESP:28ecbc:Root: 01b0b22c(Wuhong.SOSTest.Complex)
    ESP:28edfc:Root: 01b0b22c(Wuhong.SOSTest.Complex)
    ESP:28f08c:Root: 01b0b22c(Wuhong.SOSTest.Complex)
    ESP:28f09c:Root: 01b0b22c(Wuhong.SOSTest.Complex)
    ESP:28f0e0:Root: 01b0b22c(Wuhong.SOSTest.Complex)
    ESP:28f0e4:Root: 01b0b22c(Wuhong.SOSTest.Complex)
    Scan Thread
    10364 OSTHread 287c
     
      可以看到这个对象在线程1中有6个引用。
     
    5.查询对象在GC堆中的位置
      GCWhere命令显示垃圾回收堆中参数传入的位置和大小。
     
    GCWhere
    !GCWhere 0x01b0b22c
    Address Gen Heap segment begin allocated size
    01b0b22c
    0 0 01b00000 01b01000 01b0c010 0x18(24)
     
    6.查询GC堆
      只要得到对象在堆中的地址,就可以用DumpHeap显示有关GC堆的信息和和相关收统计信息。
     
    DumpHeap
    !DumpHeap 01b0b22c
    Address MT Size
    01b0b22c
    00133918 24
    01b0b244 605ff9ac
    64
    object 01b0b284: does not have valid MT
    curr_object: 01b0b284
    Last good
    object: 01b0b244
    ----------------
    02b01000 003e91d8
    16 Free
    02b01010 605b6c28
    4096
    02b02010 003e91d8
    16 Free
    02b02020 605b6c28
    528
    02b02230 003e91d8
    16 Free
    02b02240 605b6c28
    4096
    02b03240 003e91d8
    16 Free
    total
    0 objects
    Statistics:
    MT Count TotalSize
    Class Name
    00133918 1 24 Wuhong.SOSTest.Complex
    605ff9ac
    1 64 System.String
    003e91d8
    4 64 Free
    605b6c28
    3 8720 System.Object[]
    Total
    9 objects
     
      我们可以看到堆中从命令输入地址开始的对象的排列,另外我们还注意到有个对象的方法表无效了。
     
  • 其他诊断工具
  • 1.查看进程信息
      利用ProcInfo命令可以详细显示进程的环境变量、内核CPU时间和内存使用统计信息。这些信息在性能调试中非常有用。
     
    ProcInfo
    !ProcInfo
    ---------------------------------------
    Environment
    ALLUSERSPROFILE=
    C:\ProgramData
    APPDATA=
    C:\Users\Administrator\AppData\Roaming
    CommonProgramFiles=
    C:\Program Files\Common Files
    COMPUTERNAME=WUHONG
    ComSpec=
    C:\Windows\system32\cmd.exe
    FP_NO_HOST_CHECK=NO
    HOMEDRIVE=
    C:
    HOMEPATH=\Users\Administrator
    lib=
    C:\Program Files\SQLXML 4.0\bin\
    ……
    ……
    ……
    ---------------------------------------
    Process Times
    Process Started
    at: 2011 Apr 27 15:35:42.44
    Kernel CPU time :
    0 days 00:00:31.93
    User CPU time :
    0 days 00:04:15.56
    Total CPU time :
    0 days 00:04:47.49
    ---------------------------------------
    Process Memory
    WorkingSetSize: 487144 KB PeakWorkingSetSize: 497100 KB
    VirtualSize: 906484 KB PeakVirtualSize: 913984 KB
    PagefileUsage: 235248 KB PeakPagefileUsage: 243036 KB
    ---------------------------------------
    67 percent of memory is in use.

    Memory Availability (Numbers in MB)

    Total Avail
    Physical Memory
    3583 1153
    Page File
    4095 3056
    Virtual Memory 2047 1162
     
    2.查询曾经出现的OOM状况
      利用AnalyzeOOM命令可以显示对GC堆进行分配请求时发生的最后 OOM 的信息。
     
    AnalyzeOOM
    !AnalyzeOOM
    There was no
    managed OOM due to allocations on the GC heap
     
    3.查询对象所在的AppDomain
      利用FindAppDomain命令可以确定指定地址处的对象的AppDomain
      比如我们要确定DumpObj小节中类型为Wuhong.SOSTest.Complex的对象所在的AppDomain。
     
    FindAppDomain
    !FindAppDomain 0x01b0b22c
    AppDomain: 003e16b0
    Name: Wuhong.SOSTest.exe
    ID: 1
     
    4.验证GC堆或对象的有效性
      在DumpHeap小节我们注意到了在GC堆上有1个对象的方法表无效了。可以用VerifyHeap命令验证整个堆是否有损坏,也可以用VerifyObj命令验证具体的对象。
      对象损坏可能有多种原因,比如内存越界修改等。具体原因需要详细分析损坏的对象。
     
    VerifyHeap
    !VerifyHeap
    -verify will only produce output if there are errors in the heap
    object 01b0b284: does not have valid MT
    curr_object: 01b0b284
    Last good
    object: 01b0b244
    ----------------
     
     
     
     
posted @ 2011-04-28 17:47  reni  阅读(862)  评论(1编辑  收藏  举报