windbg命令手册

一. WINDBG命令手册


调试准备

为了测试 WinDbg 中使用 SOS 扩展命令,我创建了应用程序 "MemoryLeakApp.exe",Visual Studio 程序选择为 64 位环境编译。

 "MemoryLeakApp.exe" 启动运行后可能占用内存600M。

此时,选择使用 64 位 WinDbg 来调试程序。我们先通过 Attach Process 方式来调试。

当然,如果我们使用了 32 位的 WinDbg 去 Attach 进程,会直接报错。

 

WinDbg 常用命令手册

内置帮助命令
命令 描述
?

?             显示常规命令

? /D            通过 DML(Debugging Markup Language) 方式显示常规命令

.help

.help        显示 . 系列命令

.help /D       通过 DML 方式显示 . 系列命令

.help /D a*   通过 DML 方式显示所有以 'a' 字母开头的 . 系列命令

.chain

.chain          列出所有已加载的调试器扩展

.chain /D      通过 DML 方式列出所有已加载的调试器扩展

.extmatch

.extmatch /e ExtDLL FunctionFilter      显示调试器扩展的所有导出函数

.extmatch /D /e ExtDLL FunctionFilter  通过 DML 方式显示调试器扩展所有导出函数

.extmatch /D /e uext *                       显示 uext 扩展中的所有导出函数

.hh

.hh         打开 WinDbg 的帮助文件

.hh Text  打开 WinDbg 的帮助文件,并自动搜索 Text 的内容

.hh dt     在 WinDbg 帮助文件中搜索 dt 命令

调试会话命令
命令 描述
.attach

.attach PID 附加到指定ID的进程

.detach

.detach      结束调试会话,被调试进程仍可继续运行

q

q               结束调试会话,同时终止被调试进程的进行

qq             结束调试会话,同时终止被调试进程的进行

.restart

.restart      重启被调试应用

一般信息命令
命令 描述
version

显示调试器版本信息和已加载的调试器扩展

vercommand

显示调试器启动文件的路径

vertarget

显示目标机器的版本

CTRL+ALT+V

打开或关闭 Verbose 模式开关,某些命令在此模式下可以给出更多详细信息

.formats

.formats Expression  显示数字的各种格式信息

.formats 5

.cls

清理屏幕

.last event 显示最新的异常信息或事件信息
.effmach

.effmach 显示有效作用的机器信息
.effmach . 
.effmach # 
.effmach x86 | amd64 | ia64 | ebc

.time

显示系统记录的各种时间

.echo

.echo String  输出字符串

.echo "String"

.echo "Hello World"

符号加载命令
命令 描述
ld

ld ModuleName  加载指定模块的符号

ld *                  加载所有模块的符号

!sym

!sym                获取符号加载状态

!sym noisy       让调试器显示符号搜索详细信息

!sym quiet        默认项,不显示符号搜索信息

.sympath

.sympath         显示和设置符号搜索路径

.sympath+       增加符号搜索路径

.sympath+ C:\Symbols

.symopt

.symopt            显示当前符号可选项

.symopt+ Flags  添加符号可选项

.symopt- Flags   移除符号可选项

.symfix

.symfix                           设置符号库路径

.sym+ DownstreamStore  添加符号库路径

x

x [Options] Module!Symbol    模式匹配符号信息

x /t ..            根据数据类型匹配

x /v ..            显示详细信息

x /a ..            按照地址排序

x /n ..            按照名称排序

x /z ..            按照大小排序

x *!               列出所有模块

x ntdll!*          列出 ntdll 模块

x /t /v ntdll!*    列出 ntdll 模块数据类型和符号类型

.reload

.reload                            重新加载符号信息

.reload [/f | /v]                /f 强制立即加载符号 /v 显示详细信息

.reload [/f | /v] Module     Module 为指定模块加载符号信息

.reload /f @"ntdll.dll"

.reload /f @"C:\WINNT\System32\verifier.dll"

模块加载命令
命令 描述
 lm

lm[ v | l | k | u | f ] [m Pattern] 显示已加载的模块

lm   显示所有加载和未加载的模块信息

lmv 显示已加载模块的详细信息

lml  同时显示加载的符号信息

lmk 显示内核模块信息

lmu 显示用户模块信息

lmf  显示镜像路径

lmm 匹配模块名称

lmD 使用 DML 方式显示

lmv m kernel32 显示 kernel32 模块详细信息

!dlls

!dlls         列出所有加载的模块和加载数量

!dlls -i      根据初始化顺序

!dlls -l      根据加载顺序(默认项)

!dlls -m    根据内存顺序

!dlls -v     显示更多详细信息

!dlls -c ModuleAddr  仅显示 ModuleAddr 地址的模块信息

!dlls -?     显示帮助

!dlls -v -c kernel32 显示 kernel32.dll 的信息

!lmi

!lmi Module    显示模块的详细信息,包括加载符号信息

!lmi kernel32  显示 kernel32.dll 模块的信息

异常分析命令
命令 描述
!analyze

!analyze -v       显示当前异常的详细信息

!analyze -hang  诊断线程调用栈上是否有任何线程阻塞了其他线程

!analyze -f        查看异常分析信息,尽管调试器并未诊断出异常

进程信息命令
命令 描述
!dml_proc

通过 DML 方式显示当前进程的信息

.tlist

显示当前所有进程

线程信息命令
命令 描述
~

~                              显示线程信息

~* [Command]           所有线程

~. [Command]            当前线程

~# [Command]           引发当前事件或异常的线程

~Number [Command]  显示指定序号的线程

~~[TID] [Command]   显示指定线程ID的线程

~Ns                          切换到线程 N

~* k  显示所有线程的调用栈

~2 f   冻结2号线程

~# f  冻结引发异常的线程

~3 u  解除对3号线程的冻结

~2 k  显示2号线程的调用栈

~e

~* e CommandString            在所有线程上执行命令

~. e CommandString             在当前线程上执行命令

~# e CommandString            在引发异常的线程上执行命令

~Number e CommandString   在指定序号的线程上执行命令

~2e r; k; kd  相当于 ~2r; ~2k; ~2kd

~*e !gle       显示所有线程的最后一个错误信息

~f

~Thread f    冻结线程

~u

~Thread u   解除冻结线程

~n

~Thread n   挂起线程,增加线程挂起数量

~m

~Thread m  恢复线程,减少线程挂起数量

!teb

显示线程环境信息

!tls 

!tls -1          -1 为显示当前线程所有的 slot 信息

!tls SlotIdx   显示指定的 slot 信息

!tls [-1 | SlotIdx] TebAddr

.ttime

显示线程时间信息

!runaway

[Flags: 0 | 1 | 2] 显示每个线程消耗的时间,用于快速的查找 CPU 时间消耗最多的线程

0 用户态时间

1 内核态时间

2 自线程创建起的时间间隔

!gle

!gle         显示当前线程的最后错误

!gle -all    显示所有线程的最后错误

!error

!error ErrValue      解析错误信息

!error ErrValue 1   将错误值作为 NTSTATUS 代码

堆栈信息命令
命令 描述
k

k [n] [f] [L] [#Frames]  显示调用栈信息

kn      调用栈包含帧号

kf       临近帧的距离

kL       忽略源代码

kb ...  最开始的 3 参数

kp ...  所有的参数,包括参数类型、名称和值

kP ...  所有的参数

kv ...  FPO信息

kb 5   显示最开始的 5 个帧

kd

kd [WordCnt]  显示原始栈数据和可能的符号信息

kM

使用 DML 格式显示堆栈信息

.kframes

设置栈长度,默认是20(0x14)

.frame

.frame            显示当前帧

.frame #         指定帧号

.frame /r [#]   显示寄存器信息

.frame 2         显示帧号 2 的信息

.frame /r 0d    显示 0 帧中寄存器信息

!uniqstack

!uniqstack                   显示所有线程的栈信息

!uniqstack [b|v|p] [n]   b=前3个参数;v=FPO信息;p=所有参数;n=帧号

!uniqstack -?               显示帮助

!findstack

!findstack Symbol              找到包含符号或模块的栈

!findstack Symbol [0|1|2]   0=仅显示线程ID;1=线程ID和帧;2=全部的线程栈;

!findstack -?                      显示帮助

!findstack clr 2                   显示包含 clr 的所有栈的信息

扩展帮助命令
命令 描述

!Ext.help

常规扩展命令帮助

!Exts.help

 

!Uext.help

用户态模式扩展命令帮助

!Ntsdexts.help

用户态扩展命令帮助(OS相关)

!logexts.help

日志相关扩展

!clr10\sos.help

调试托管代码

!wow64exts.help

wow64调试器扩展

!Wdfkd.help

内核态驱动框架扩展

!Gdikdx.help

图形驱动扩展

!NAME.help

显示任何 NAME 名称的扩展命令的帮助
日志扩展命令
命令 描述

!logexts.help

 显示所有日志扩展命令

!loge

!loge [dir]  打开日志功能,可选配置输出目录

!logi

初始化日志功能

!logd

关闭日志功能

!logo

!logo                    列出日志配置信息

!logo [e|d] [d|t|v]  打开或关闭日志,d=调试器,t=文本文件,v=详细信息

!logc

!logc                        列出所有日志类型

!logc p #                  列出 # 中的日志类型

!logc [e|d] *              打开或关闭所有日志类型

!logc [e|d] # [#] [#]  打开或关闭日志类型 #

!logb

!logb p  打印缓冲区信息至调试器

!logb f   刷新缓冲区内容之日志文件

!logm

!logm                          显示模块的包含或屏蔽列表

!logm [i|x] [DLL] [DLL]  指定模块的包含或屏蔽列表



二.WINDBG SOS 扩展命令手册



SOS 调试命令手册

扩展加载命令
命令 描述
.loadby

.loadby sos clr 

.load

.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll

对象审查命令
命令 描述

!DumpObj (do)

!DumpObj               显示指定地址的对象的信息。

!DumpObj -nofields 在显示结果中不显示字段信息,这对类似 String 类型等非常有用

!DumpArray (da)

!DumpArray                 检查数组对象元素

!DumpArray -start        可选项,只支持一维数组,从指定索引处开始显示数组元素

!DumpArray -length      可选项,只支持一维数组,指定显示元素的数量

!DumpArray -details      可选项,通过使用 !DumpObj 和 !DumpVC 来打印更多详细信息

!DumpArray -nofields    可选项,仅在 -details 选项使用时有效,不显示对象的字段信息

!DumpStackObjects (dso)

!DumpStackObjects            显示当前调用栈上的所有托管对象的信息,可配合 k 或 CLRStack 命令使用

!DumpStackObjects -verify  将对非静态类中的所有字段进行检查

!DumpHeap

!DumpHeap 将遍历 GC 堆对对象进行分析。通过指定不同的选项,可以查看特定的类型、数组和锁。

                  如果不加任何选项,该命令的输出首先为堆中对象的列表,然后是包含已发现类型的列表、大小和数量的报表。

其中 “Free” 对象代表的是垃圾回收器可以使用的区域。如果此区域的大小超过30%则可能意味着出现了堆碎片。

这通常是由于某些对象被持有了较长时间,并且结合了大量高频率的内存分配。

!DumpHeap 会针对此情况提供一个关于堆碎片化的警告。

-stat              限定输出为类型统计分析的汇总

-strings          限定输出为字符串类型的统计分析汇总

-short            限定输出仅为对象的地址,这将为串行化命令调试带来便利

-min <size>    忽略尺寸小于给定的 bytes 值的对象

-max <size>   忽略尺寸大于给定的 bytes 值的对象

-live               仅输出仍然存活的对象

-dead             仅输出已死亡的对象 (这些对象将在下一个 Full GC 中被回收)

-thinlock         ThinLocks 的报告 (参考 !SyncBlk)

-startAtLowerBound              强制堆指向可使用的地址的低地址边界

-mt <MethodTable address>  仅列出包含 MethodTable 的对象

-type <partial type name>     仅列出对象类型字符串中包含给定子字符串的对象

start               从给定地址处开始列出对象

end                 从给定地址处停止检索

start/end 的参数可以通过 !EEHeap -gc 命令来获取。例如,下面的图中显示列出大对象堆中的对象。

!DumpVC

!DumpVC <MethodTable address> <Address>  

检查值类型对象的字段,在 C# 中指的是 struct,存活于栈中或者被装箱为 Object 后存放在 GC 堆中。

需要为 SOS 提供值对象的方法表地址,因为值对象与一级对象不同,一级对象的第一个字段即为方法表。

!GCRoot

!GCRoot [-nostacks] <Object address>  查询一个对象的所有引用根。

对象的引用根可能存在于如下位置:

  1. 栈上
  2. 包含在 GC 句柄中
  3. 准备被终结的对象中
  4. 在上述三点中的对象的成员中

在查询引用根时,首先在栈上查询,然后是句柄表,最后是对象终结器中的队列中的可达对象。

注:!GCRoot 不会栈上的对象根进行有效性校验。可以使用 !CLRStack 或 !U 来检查对象是否仍在被使用。

-nostacks   限定仅在句柄表和终结器队列中查找。

!ObjSize

!ObjSize [<Object address>]  

如果不加参数,!ObjSize 将列出托管线程中所有对象的尺寸。

同时,也会列出进程中的所有 GC 句柄,和句柄指向对象的大小。

在计算对象的尺寸时,!ObjSize 将计算对象及其所有子对象的大小。

!FinalizeQueue

!FinalizeQueue [-detail] | [-allReady] [-short]

!FinalizeQueue   列出所有注册为终结化的对象。

GC 堆是按照代来划分,此处同样列出每代中将被终结的对象的数量。

上图中显示了只有 0 代堆中包含了注册终结对象。"(0015bc90->0015bca0)" 提示了对象指针的内存查询区域。

-allReady   指定此选项后,将列出所有准备终结化的对象,无论其是否被标注为在当前轮 GC 还是下一轮 GC。

                那些已经不在 "Ready for finalization" 列表中的对象则已经失去了引用根。

                这个选项可能会有些开销,因为其会验证是否终结化队列中的对象是否仍然存在引用根。

-short       限定输出仅为对象的地址。

                如果与 -allReady 选项同时使用,则将列出所有存在终结器中并且不再是引用根的对象。

                如果单独使用,则将列出 "Ready for finalization" 队列中的所有对象。

-detail       显示额外的信息,例如需要被终结器清理的缓存的数据结构等。

!PrintException (pe)

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

!PrintException 将对任意 System.Exception 的衍生对象的字段进行格式化。

                       例如,将对 _stackTrace 字段进行格式化。

                       如果不加任何参数,!PrintException 将查找当前线程上最有一个出现的异常。

                       这与使用 !Threads 中显示的异常是相同的。

-nested 显示嵌套的异常信息。

-lines    显示异常的可用的源信息。

!TraverseHeap

!TraverseHeap [-xml] [-verify] <filename>

!TraverseHeap  将以一种 CLR Profiler 可理解的格式将 GC 堆信息输出到文件。

可以在如下链接下载 CLR Profiler:

http://www.microsoft.com/downloads/details.aspx?FamilyId=86CE6052-D7F4-4AEB-9B7A-94635BEEBDDA&displaylang=en

CLR Profiler 将以图形化的方式来帮助分析应用程序 GC 堆的状态。

-verify  将进行更多合法性检测,可在有任何疑似堆腐化时使用。

-xml     输出格式指定为 XML 格式。

数据结构审查命令
命令 描述

!DumpDomain

!DumpDomain [<Domain address>]

在无参数时,!DumpDomain 将列出进程中所有的 AppDomain 。同时也会遍历所有已加载的程序集。

在应用程序的的 AppDomain 之外,还存在另外两个特殊的应用程序域:Shared Domain 和 System Domain。

所列出的任意程序集的指针均可用于 !DumpAssembly 命令。任何 AppDomain 指针均可被使用于 !DumpDomain 命令。

!EEHeap

!EEHeap [-gc] [-loader]  遍历进程内存中的 CLR 数据结构。

!EEHeap -gc

!EEHeap -loader

!Name2EE

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

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

!Name2EE 用于将给定的类名称转换为 MethodTable 或 EEClass 的地址。或将方法名称转换为 MethodDesc。

!SyncBlk

!SyncBlk [-all | <syncblk number>]

SyncBlock 负责持有一些不是为每个对象都需创建的额外信息,例如 COM Interop 数据、HashCodes、锁信息等。

例如,假设有如下代码:

lock (MyObject)
{
  ...  
}

则将设置 MyObject 为当前线程所拥有。一个 SyncBlock 将会为 MyObject 创建,并且包含线程的宿主信息等。

如果另外一个线程试图执行同样的代码,该线程将不能进入该 Block 中直到上一个线程退出。

这将使 !SyncBlk 在检测托管线程死锁时非常有用途。例如有如下代码情形:

复制代码
Resource r1 = new Resource();
Resource r2 = new Resource();

lock (r1)
{
  lock (r2)
  {
    ...
  }
}

lock (r2)
{
  lock (r1)
  {
    ...
  }
}
复制代码

通过上面的描述可以了解到,线程 e04 持有着对象 00a7a194,而线程 ab8 持有着对象 00a7a1a4。

再结合调用栈信息可发现死锁。

此处,可通过运行 !U 或 !DumpHeap -ThinLock 获取更多信息。

!DumpMT

!DumpMT [-MD] <MethodTable address>  显示方法表。每个托管对象都在其起始位置包含一个方法表指针。

-MD 显示对象中定义的方法列表。

!DumpClass

!DumpClass <EEClass address> 显示 EEClass 中定义的属性和字段类型。

EEClass 是一种描述对象类型的数据结构。

!Token2EE

!Token2EE <module name> <token>  将 Token 元数据转换为 MethodTable 或 MethodDesc。

!EEVersion

显示 CLR 版本。同时也显示应用程序代码是运行在 "Workstation" 或 "Server" 模式。

类似的功能可以通过命令:"lm v m clr"

!DumpModule

!DumpModule [-mt] <Module address>  通过模块地址获取模块信息。

-mt 显示模块内定义的类型信息。

!ThreadPool

显示线程池的基本信息,包括队列中请求的数量、完成端口线程的数量和计时器的数量。

!DumpAssembly

!DumpAssembly <Assembly address> 显示指定地址程序集的信息。

!DumpSigElem

!DumpSigElem <sigaddr> <moduleaddr>  显示签名对象中的一个指定元素信息。

!DumpRuntimeTypes

!DumpRuntimeTypes  从 GC 堆中寻找 System.RuntimeType 类型的对象,并且打印类型名称和方法表。

!DumpSig

!DumpSig <sigaddr> <moduleaddr>  显示给定地址的方法或字段的签名信息。

!RCWCleanupList

!RCWCleanupList [address]  显示在下一次清理周期内回收的 COM 对象信息。

RuntimeCallableWrapper 是 CLR 内部的数据结构,用于宿主 COM 对象。

通过 System.__ComObject 类向托管代码暴露。

当相应的对象被 GC 回收之后,相关的 COM 对象引用也不在需要,所以相应的 RCW 也需要被清理。

!DumpIL

!DumpIL <Managed DynamicMethod object> | 
              <DynamicMethodDesc pointer> |
              <MethodDesc pointer> |
               /i <IL pointer>

打印托管方法的 IL 代码。在调试 DynamicMethod 时非常有效,但同样适合 non-DynamicMethod。

可以在下列 4 种条件下使用:

  1. 如果使用了 System.Reflection.Emit.DynamicMethod 对象,则可将指针作为第一个参数。
  2. 如果使用了 DynamicMethodDesc 指针,可以打印相关动态方法的 IL 代码。
  3. 如果使用了常规的 MethodDesc,可以将其作为第一个参数来查看 IL 代码。
  4. 如果有直接的 IL 指针,则可使用 /i 选项和 IL 地址作为参数。

!DumpRCW

!DumpRCW <RCW address>                 显示 RuntimeCallableWrapper 的信息。

!DumpCCW

!DumpCCW <CCW address or COM IP>  显示 COMCallableWrapper 的信息。
代码堆栈审查命令
命令 描述

!Threads

!Threads [-live] [-special]  列出进程中所有的托管线程。

-live        可选项。仅显示活跃的线程。

-special   可选项。显示由 CLR 创建的特殊线程,这些线程有可能不是托管线程。

              例如 GC 线程、调试器线程、终结器线程、应用程序域卸载线程、线程池计时器线程等。

ID 列涵义:

  1. 调试器用 ID
  2. CLR 线程 ID
  3. OS 线程 ID

!ThreadState

!ThreadState value   显示线程状态

可能的线程状态包括:

  • Thread Abort Requested
  • GC Suspend Pending
  • User Suspend Pending
  • Debug Suspend Pending
  • GC On Transitions
  • Legal to Join
  • Yield Requested
  • Hijacked by the GC
  • Blocking GC for Stack Overflow
  • Background
  • Unstarted
  • Dead
  • CLR Owns
  • CoInitialized
  • In Single Threaded Apartment
  • In Multi Threaded Apartment
  • Reported Dead
  • Fully initialized
  • Task Reset
  • Sync Suspended
  • Debug Will Sync
  • Stack Crawl Needed
  • Suspend Unstarted
  • Aborted
  • Thread Pool Worker Thread
  • Interruptible
  • Interrupted
  • Completion Port Thread
  • Abort Initiated
  • Finalized
  • Failed to Start

!IP2MD

!IP2MD <Code address>  根据给定的托管 JITTED 代码,查找相关的 MethodDesc。

上面的例子中,我们通过 Mainy.Main 的返回地址来寻找相关的方法信息。

!U

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

根据给定方法的 MethodDesc 指针,输出反汇编代码。

-gcinfo  同时获得方法的 GCInfo 信息。相关信息可通过 !GCInfo 获得。

-ehinfo  同时获得方法的异常信息。相关信息可通过 !EHInfo 获得。

-n         不显示行号和符号等信息。

!DumpStack

!DumpStack [-EE] [-n] [top stack [bottom stack]]   提供详细甚至过于冗余混淆的调用栈信息。

-EE  仅显示托管函数。

-n    不显示行号或符号信息。

!EEStack

!EEStack [-short] [-EE]  这个命令用于在进程内的所有线程上运行 !DumpStack。

-EE      该选项将直接被传递给 !DumpStack 命令。

-short  尝试仅显示可能感兴趣的线程,包括:

  1. 线程获取了一个锁
  2. 线程为 "jijacked" 状态,并允许被 GC 回收
  3. 线程当前运行至托管代码

!CLRStack

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

!CLRStack [-a] [-l] [-p] [-i] [variable name] [frame]

!CLRStack 试图仅为托管代码提供真实的调用栈信息。

-p    显示托管函数的参数信息。

-l     显示帧内局部变量的信息。

-a    = -p + -l 的组合。

-n    不显示行信息和符号信息。

!GCInfo

!GCInfo (<MethodDesc address> | <Code address>) 用于诊断 JIT 编译器是否存在Bug。

!EHInfo

!EHInfo (<MethodDesc address> | <Code address>)  用于显示 JITTED 方法的异常处理部分。

!BPMD

!BPMD [-nofuturemodule] <module name> <method name> [<il offset>]

!BPMD <source file name>:<line number>

!BPMD -md <MethodDesc>

!BPMD -list

!BPMD -clear <pending breakpoint number>

!BPMD -clearall

!BPMD 用于提供托管代码的断点支持。

!COMState

显示进程的 COM Apartment Model。
垃圾回收历史审查命令
命令 描述

!HistInit

!HistInit 在运行任何 Hist 族命令之前,需要先根据被调试程序的压缩日志中初始化 SOS 结构。

!HistRoot

!HistRoot <root>  显示 promotion 和 relocation 信息。

!HistObj

!HistObj <obj_address>  从日志中检查 GC relocation 链。

!HistObjFind

!HistObjFind <obj_address>  从日志中检索与对象的 relocation 相关的所有信息。

!HistClear

!HistClear  释放用于 Hist 族命令的所有资源。通常无需显式的调用此命令,因为每次 HistInit 会首先清理资源。

诊断工具命令
命令 描述

!VerifyHeap

!VerifyHeap 是一个用于检测 GC 堆中是否有腐化迹象的诊断工具。

其以如下的模式逐个的走查对象:

!VerifyObj

!VerifyObj <object address> 是一个用于检查被传递的对象参数是否存在腐化的迹象的诊断工具。

!FindRoots

!FindRoots -gen <N> | -gen any | <object address> 用于查找对象的引用根的诊断工具。

!HeapStat

!HeapStat [-inclUnrooted | -iu]  显示GC堆中每个代的大小和总和,同时显示空闲空间的大小。

-inclUnrooted  报告中包含那些在 GC 堆中已标识为不再引用的托管对象。

!GCWhere

!GCWhere <object address>  显示指定对象在 GC 堆中的位置。

!ListNearObj (lno)

!ListNearObj <object address>  用于显示对象前后的对象的诊断工具。

!GCHandles

!GCHandles [-type handletype] [-stat] [-perdomain]  提供对进程中 GCHandles 的统计分析。

-stat            仅显示统计信息,而不列出句柄和其指向的信息。

-perdomain   根据 AppDomain 来显示统计信息。

-type            句柄类型的过滤。

可用的句柄类型包括:

  • Pinned
  • RefCounted
  • WeakShort
  • WeakLong
  • Strong
  • Variable
  • AsyncPinned

!GCHandleLeaks

!GCHandleLeaks  帮助检测 GCHandle 泄漏的工具。

!FindAppDomain

!FindAppDomain <Object address>  尝试根据对象查找出 AppDomain。

!SaveModule

!SaveModule <Base address> <Filename>  将内存镜像保存至文件。

!ProcInfo

!ProcInfo [-env] [-time] [-mem]  列出进程中的环境变量,内核 CPU 时间,内存使用率等。

!StopOnException (soe)

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

!StopOnException 当需要调试器在遇到特定的托管异常时停止。

例如,当遇到 System.OutOfMemoryException 时停止,而遇到其他异常时继续运行。

!DumpLog

!DumpLog [-addr <addressOfStressLog>] [<Filename>]  允许将 CLR in-memory stress log 日志写入文件。

通过下面注册表内的信息更改 Stress Log 设置:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework:

(DWORD) StressLog = 1

(DWORD) LogFacility = 0xffffffbf 

(DWORD) StressLogSize = 65536

(DWORD) LogLevel = 6

LogFacility 定义:

  • GC            0x00000001
  • GCINFO         0x00000002
  • STUBS          0x00000004
  • JIT                0x00000008
  • LOADER        0x00000010
  • METADATA     0x00000020
  • SYNC            0x00000040
  • EEMEM          0x00000080
  • GCALLOC      0x00000100
  • CORDB         0x00000200
  • CLASSLOADER 0x00000400
  • CORPROF       0x00000800
  • REMOTING      0x00001000
  • DBGALLOC     0x00002000
  • EH                 0x00004000
  • ENC               0x00008000
  • ASSERT         0x00010000
  • VERIFIER        0x00020000
  • THREADPOOL  0x00040000
  • GCROOTS       0x00080000
  • INTEROP         0x00100000
  • MARSHALER    0x00200000
  • IJW                0x00400000
  • ZAP                0x00800000
  • STARTUP         0x01000000
  • APPDOMAIN     0x02000000
  • CODESHARING 0x04000000
  • STORE             0x08000000
  • SECURITY        0x10000000
  • LOCKS             0x20000000
  • BCL                 0x40000000

!VMMap

!VMMap  遍历虚拟地址空间,列出 Region Protection 类型。

!VMStat

!VMStat  提供虚拟地址空间的综合报告。

!MinidumpMode

!MinidumpMode <0 or 1>

通过 ".dump /m" 或 ".dump" 来获得 CLR 数据的子集,仅适合使用 SOS 的命令的子集,一些 SOS 命令可能失败。

默认值为 0。

!AnalyzeOOM (ao)

!AnalyzeOOM 显示最后一个 OOM 的信息。




三. WINDBG  SOSEX 扩展命令手册


SOSEX 调试命令手册

扩展加载命令
命令 描述
.load

.load sosex

.load C:\Program Files (x86)\Windows Kits\8.1\Debuggers\x64\sosex.dll

SOSEX扩展命令
命令 描述

!bhi

!bhi [filename]    BuildHeapIndex  用于对 GC 堆内的对象构建一个索引文件。

这将使 !gcroot 和 !refs 命令工作的更加快速。

索引内容将被存储到给定的文件名的文件中。

如果未指定文件名,则默认的文件名为 %dumppath%\%dumpname%_heapindex.bin 。

!chi

!chi   ClearHeapIndex  释放堆索引使用的所有资源,并从内存中移除。

!dlk

!dlk [-d]   检测 SynczBlock 死锁。

-d           同时也检测 ReaderWriterLock 或 ReaderWriterLockSlim 的衍生类。

!dumpfd

!dumpfd <FieldAddr>    显示 FieldDef 结构的属性值。

!dumpgen

!dumpgen <intGenNum> [-free] [-stat] [-type <TYPE_NAME>] [-nostrings]

以如下格式显示指定代的内容:

hexAddr decSize strTypeName

-nostrings    不显示对象名称或字符串数据。

-free            仅包括 FREE 的对象类型。

-stat            仅显示一个综合的统计。

-type           仅包含类型名称字符串中包含给定子字符串的对象数据。

!finq

!finq [GenNum] [-stat]  显示终结化队列中的对象,并根据代来分类。

GenNum    给定的代(generation)。

-stat         显示统计信息。

!frq

!frq [-stat]   显示可达队列(Freachable Queue)中的对象。

!gcgen

!gcgen <hexObjectAddr>  获取给定对象在 GC Heap 中的代数。如果对象在 LOH 中,则会提示 “Large Object Heap”。

!gch

!gch [-HandleType] [-stat]  列出所有 GCHandle 实例。

-HandleType 指定句柄的类型。!gch -Pinned -Strong

-stat           根据句柄类型进行统计。

有效的类型有:

  • WeakShort
  • WeakLong
  • Strong
  • Pinned
  • Variable
  • RefCounted
  • AsyncPinned

!lhi 

!lhi [filename]     LoadHeapIndex 从给定的文件中加载堆索引。

如果未指定文件名称,则默认的文件名称为 %dumppath%\%dumpname%_heapindex.bin。

!mbc 

!mbc <Managed Breakpoint ID | *>    移除指定 ID 的断点。* 为移除全部。

!mbd 

!mbd <Managed Breakpoint ID | *>   使失效,但不移除断点。

!mbe 

!mbe <Managed Breakpoint ID | *>    使断点生效。

!mbl 

!mbl <Managed Breakpoint ID>          显示给定 ID 的断点,或列出所有托管断点及其状态。

!mbm 

!mbm <method filter> [ILOffset] [Options]  在指定的方法及偏移处设置断点。

!mdso

!mdso [Options]    显示在当前上下文中,对象在栈上和 CPU 寄存器中的引用。

/a               显示栈上所有对象的引用。

/r               仅显示寄存器中的对象。

/c:n            限定显示的对象的数量为 n。

/t:typeFilter 限制显示的对象的类型。

/mt:MT       限制显示的对象为指定的方法表。

!mdt 

!mdt [typename | paramname | localname | MT] [ADDR] [-r[:level]] [-e[:level]] [-start:index] [-count:n]

显示指定对象或类型的字段信息。

-r   递归显示字段信息。

-e   指定的类型将被扩展。

!mdv 

!mdv [nFrameNum]    显示当前帧中的参数或局部变量的信息。帧来自 !mframe 命令。

!mfrag 

!mfrag [-stat] [-mt:<MT>]    输出空闲的块报告。

-stat      显示统计报告

-mt:MT   仅显示碎片信息

!mframe 

!mframe [frame number]    为 !mdt 或 !mdv 命令设置当前的托管帧。

!mgu

!mgu   返回在当前调用栈中最后一个托管调用者的当前位置。

!mk 

!mk [-l] [-p] [-a] [-c] [-cc]    显示调用栈中托管和非托管帧的组合。

-l    显示局部变量

-p   显示参数

-a   显示局部变量和参数(Locals + Parameters)

-c   清理

-cc  清理,同时也拆解名空间。

!mln

!mln [address expression]    显示给定地址处的 CLR 数据类型。

!mlocks 

!mlocks [-d]    显示线程中所有的托管锁对象和 CriticalSections 对象。

-d   同样搜索 ReaderWriterLock 或 ReaderWriterLockSlim 的衍生类。

!mroot 

!mroot <ObjectAddr> [-all]    显示指定对象的 GC 根。

通常情况,仅显示第一个 Root 路径。

-all 显示所有的路径,这可能会耗费较长的时间。

!mt

!mt   步进至当前位置的托管方法。

!mu 

!mu [address] [-s] [-il] [-n]  显示托管和非托管反汇编的交叉信息。

-s   显示源代码,如果可用。

-il   显示 IL 反汇编程序。

-n   显示原生的反汇编程序。

默认情况为 IL 和 Native 均显示。

!muf

!muf [MD Address | CodeAddress]  [-s] [-il] [-n]   根据给定的 MD 信息进行反汇编,并显示交叉信息。

-s   显示源代码,如果可用。

-il   显示 IL 反汇编程序。

-n   显示原生的反汇编程序。

默认情况为 IL 和 Native 均显示。

 

!mwaits

!mwaits [-d | LockAddr]    显示所有正在等待的线程。如果可知的话,同时显示正在等待的锁的信息。

-d            同样搜索 ReaderWriterLock 或 ReaderWriterLockSlim 的衍生类。

LockAddr  列出所有等待该地址锁的线程。

-d 和 LockAddr 选项是互斥的。

!mx

!mx <Filter String>    显示任意匹配的类型、方法、字段等。

!rcw

!rcw [Object or SyncBlock Addr]  显示 RuntimeCallableWrapper 数据。

!refs

!refs <hexObjectAddr> [-target|-source]    列出指定对象的所有的引用。

-source    仅显示指定对象所持有的引用。

-target     仅显示持有指定对象的引用。

格式化的输出采用如下格式:

hexAddr decSize strTypeName

!rwlock

!rwlock [ObjectAddr | -d]    显示所有的 RWLock。如果给定 RWLock 地址,则显示该锁的详细信息。

-d            同样搜索 ReaderWriterLock 或 ReaderWriterLockSlim 的衍生类。

!strings

!strings [ModuleAddress] [Options]    在托管堆或指定的模块中搜索匹配的字符串信息。

可选项:

g:<min gen>        列出指定 GC 代数中的字符串。有效的参数为 0、1、2 和 3(LOH)。

m:<match filter>  显示指定匹配规则的字符串。

n:<min length>    显示字符串的长度的最小值。

x:<max length>   显示字符串的长度的最大值。



猜你喜欢

转载自blog.csdn.net/qq1263575666/article/details/79140965