首页 > 代码库 > SOS 调试扩展 (SOS.dll) 《第五篇》

SOS 调试扩展 (SOS.dll) 《第五篇》

  SOS调试扩展让你可以查看在公共语言运行时里面运行的代码的有关信息。例如,你可以使用SOS调试扩展显示托管堆的有关信息,查找堆的错误,显示运行时使用的内部数据类型,以及查看在运行时里面运行的所有托管代码的有关信息。

  使用SOS调试扩展的办法是把它装入到WinDbg.exe调试器,或者Visual Studio 2005或它的更早版本。你能够在WinDgb.exe里或者在Visual Studio的即时窗口里面执行令来载入它。

  在Windbg.exe中装载SOS的命令是:

.loadby sos mscorwks

  如果使用的.Net版本不同,那么还可以手动指定版本,如手动指定载入4.0版本命令:

.load C:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/sos.dll

  SOS.dll 随 .NET Framework 安装在 %windir%\microsoft.net\framework\<.NET 版本> 目录下。

 

  SOS扩展命令列表:

命令 描述

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。

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栏的结果。