使用WinDbg调试.NET代码
在开发以.NET编程的软件经常会需要调试,一般的使用VS来调试就可以了。但有时你会发现你没有安装VS,或者有些问题用VS不好看出问题,这是就可以选择WinDBG。下面列出一些经常用到的命令。
一、 有两种方式可以挂上被调试程序:
1、使用WinDBG直接打开可运行程序(Ctrl+E)
这时WinDBG还没有加载mscorwks.dll,不能加载SOS.DLL。需要使用命令
sxe ld:mscorwks //这命令是再加载了mscorwks后WinDBG会断下来,这样就有机会加载SOS。
2、使用WinDBG直接挂上被调试程序(F6)
使用lmm mscorwks命令看是否加载了mscorwks,如果没有加载就使用按照上面方式做
再就是加载SOS.DLL,使用命令格式如下:
.load <full path to sos.dll> //使用这个命令自己指定和.NET匹配的SOS
.loadby sos mscorwks //使用这个命令根据已加载的mscorwks来确定并加载SOS
可以使用.chain开查看加载的SOS
注意:使用方式1的直接运行程序,加载过SOS后直接使用!bpmd到设置断点到Main方法好像不行,反正我是试过是这样,不知道其他人是否也是如此,下面就是我输入的,但是好像我直接跑的话是不会停的。
0:000> !bpmd certexport certexport.Program.main
Adding pending breakpoints...
对于这情况我一般使用如下方法:
bp mscorwks!Assembly::GetEntryPoint,这个地方返回的是EntryPoint对于的MethodDesc pointer。
0:000> bp mscorwks!Assembly::GetEntryPoint //1、设置断点
0:000> g
Breakpoint 1 hit
eax=0014f57c ebx=00000000 ecx=002d7e18 edx=0000000d esi=00000200 edi=00000000
eip=706fe154 esp=0014f55c ebp=0014f7b0 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
mscorwks!Assembly::GetEntryPoint:
706fe154 682c020000 push 22Ch
0:000> gu //2、执行到这个函数返回,它返回的是EntryPoint对应的MD
eax=00242ff4 ebx=00000000 ecx=706fe241 edx=80000001 esi=00000200 edi=00000000
eip=706b0b48 esp=0014f560 ebp=0014f7b0 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
mscorwks!Assembly::ExecuteMainMethod+0x89:
706b0b48 8bf0 mov esi,eax
0:000> r eax //3、eax中存的就是EntryPoint对应的MD,这里是方法Main
eax=00242ff4 //可以使用命令!bpmd –md 00242ff4在Main方法处下断点。
下面可以看看00242ff4是否对应的是Main函数的MethodDesc Pointer
0:000> !name2ee CertExport CertExport.Program
Module: 00242c5c (CertExport.exe)
Token: 0x02000002
MethodTable: 00243008
EEClass: 002413a0
Name: CertExport.Program
0:000> !dumpmt -md 00243008
EEClass: 002413a0
Module: 00242c5c
Name: CertExport.Program
mdToken: 02000002 (E:\study_Prj\CertExport\CertExport\bin\Debug\CertExport.exe)
BaseSize: 0xc
ComponentSize: 0x0
Number of IFaces in IFaceMap: 0
Slots in VTable: 6
--------------------------------------
MethodDesc Table
Entry MethodDesc JIT Name
6fa06a90 6f881248 PreJIT System.Object.ToString()
6fa06ab0 6f881250 PreJIT System.Object.Equals(System.Object)
6fa06b20 6f881280 PreJIT System.Object.GetHashCode()
6fa774c0 6f8812a4 PreJIT System.Object.Finalize()
0024c015 00243000 NONE CertExport.Program..ctor()
0024c011 00242ff4 NONE CertExport.Program.Main(System.String[])
二、常用命令
1、设置断点
!bpmd
Usage: !bpmd -md <MethodDesc pointer>
Usage: !bpmd <module name> <managed function name>
如:
待续........