WinDbg+SOS实例
出自
SOS: It’s Not Just an ABBA Song Anymore(John Robbins)
http://msdn.microsoft.com/msdnmag/issues/03/06/Bugslayer/
源码:
//——————————————————–
using System ;
using System.Diagnostics ;
namespace ExceptApp
{
enum Days { Sat = 1 , Sun , Mon , Tue , Wed , Thu , Fri } ;
class DoSomething
{
public void Doh ( String StrParam , Days ValueParam )
{
Console.WriteLine ( StrParam ) ;
Console.WriteLine ( ValueParam.ToString ( ) ) ;
throw new ArgumentException ( "Throwing an exception" , "x" ) ;
}
public void Reh ( int i , String StrParam )
{
Console.WriteLine ( "Reh = " + i ) ;
String s = "Tommy can you see me? " + StrParam ;
Days e = Days.Fri ;
Doh ( s , e ) ;
}
public void Mi ( Object o )
{
Console.WriteLine ( "Mi = " + o.ToString ( ) ) ;
String LocalStr = "Can you see me?" ;
Reh ( 0x42 , LocalStr ) ;
}
public void Fa ( )
{
Mi ( this ) ;
}
}
class Class1
{
static void Main(string[] args)
{
try
{
DoSomething x = new DoSomething ( ) ;
x.Fa ( ) ;
}
catch
{
}
}
}
}
1. 何让WinDbg 拦截CLR Exception
使用菜单Debug->Event Filter打开Dialog
Click "Add"
enter "0xE0434F4D"
Select "Enabled" in the Execution group box
select "Not Handled" in the Continue group box
2. 使用 !thread 显示进程或一个dump文件中所有的managed线程
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 188 00181148 a020 Enabled 013c4b6c:013c5fe8 0014f238 0 MTA System.ArgumentException (013c4ad0)
2 2 94c 0018ae58 b220 Enabled 00000000:00000000 0014f238 0 MTA (Finalizer)
OSID为 win32 thread id
Domain 线程所在的app domain
Exception 可能包含多种含义, 以上的信息表明1号线程引发了ArgumentException, 2号线程是Finalizer
这个字段的值还可能是 (Threadpool Worker), (Threadpool Completion Port), or (GC),这些
都是.net的执行线程.
3. 使用Windbg的 ~ 系列命令
~ : 显示所有的线程
~* : 显示所有的线程
~. : 显示当前线程
~# : 引发异常的线程
~2 : 2号线程
使用~会显示
. 0 Id: b64.188 Suspend: 1 Teb: 7ffde000 Unfrozen
1 Id: b64.a14 Suspend: 1 Teb: 7ffdd000 Unfrozen
2 Id: b64.94c Suspend: 1 Teb: 7ffdc000 Unfrozen
可见, 进程中除了2个.net线程,还存在一个win32线程.
4. 使用 !clrstack (或!dumpstack)
!clrstack -a 查看所有信息,包括参数和局部变量
!clrstack -l 查看局部变量
!clrstack -p 查看参数
~*e!clrstack 查看所有线程的调用栈.
使用 !clrstack -a 显示
OS Thread Id: 0x188 (0)
ESP EIP
0012f350 7c81eb33 [HelperMethodFrame: 0012f350]
0012f3f4 00df02e7 ExceptApp.DoSomething.Doh(System.String, ExceptApp.Days)
PARAMETERS:
this = 0x013c1c44
StrParam = 0x013c3f18
ValueParam = 0x00000007
0012f418 00df0237 ExceptApp.DoSomething.Reh(Int32, System.String)
PARAMETERS:
this = 0x013c1c44
i = 0x00000042
StrParam = 0x013c1c6c
LOCALS:
<CLR reg> = 0x013c3f18
0x0012f41c = 0x00000007
0012f438 00df01a0 ExceptApp.DoSomething.Mi(System.Object)
PARAMETERS:
this = 0x013c1c44
o = 0x013c1c44
LOCALS:
0x0012f438 = 0x013c1c6c
0012f450 00df0134 ExceptApp.DoSomething.Fa()
PARAMETERS:
this = 0x013c1c44
0012f458 00df00b8 ExceptApp.Class1.Main(System.String[])
PARAMETERS:
args = 0x013c1c34
LOCALS:
0x0012f458 = 0x013c1c44
0012f69c 79e88f63 [GCFrame: 0012f69c]
以上内容对应于.net2.0 和原文中有所不同.
5. 使用dd 0x**** 可以查看内存中的值
6. !DumpMT [-MD] <MethodTable address>
显示位于某个地址的 method table的信息, 每个managed object都会有个method table
7. !DumpClass 显示class所有信息
8. !Dumpmodule
9. !Dumpobject
对于一个static 变量,会显示domain 和 静态变量在domain中位置, 这些信息被>>和<<扩起.
790fa3e0 4000099 10 System.String 0 shared static Empty
>> Domain:Value 0014f238:790d6584 <<
10.!DumpStackObjects 显示当前线程的堆栈上的所有对象.
