程序员都知道,在生产环境中,如果没有系统日志,对问题的分析将非常的困难。即使有日志,有时候也会因为日志记录的不全面,而导致问题不能分析清楚。其实,Windbg里面有Live Debug功能,正好可以借鉴应用。
本文介绍使用Windbg在.net程序中设置断点调试的方法。Windbg在Native Code里面下断点是比较方便的,bp加上一个内存地址就可以做到。下面进入正题。
下面是一段程序,编译运行的程序名为MyApp.exe。
class Program
{
static void Main(string[] args)
{
System.Console.WriteLine("Press any key to be continue...");
Test("Hello");
System.Console.ReadLine();
}
public voidTest(string data)
{
Console.WrilteLine(data);
}
}
加入现在要对Test方法设置断点,查看data参数的情况。步骤如下:
步骤一:加载 clr
0:000>.loadby sos clr
步骤二:列示Program类型所有方法的信息,并找到 Test方法的MethodTable地址
0:000> !name2ee *!MyApp.Program
Module: 790c2000 (mscorlib.dll)
--------------------------------------
Module: 00a82c3c (MyApp.exe)
Token: 0x02000002
MethodTable: 00a83038
EEClass: 00a811d8
Name: MyApp.Program
步骤三:得到了Program类的MethodTable的地址了,获取MethodTable详细信息,找到Test方法的MethodDesc信息。
0:000> !dumpmt -md 00a83038
EEClass: 00a811d8
Module: 00a82c3c
Name: MyApp.Program
mdToken: 02000002 (E:"myProject"MyApp"MyApp"bin"Debug"MyApp.exe)
BaseSize: 0xc
ComponentSize: 0x0
Number of IFaces in IFaceMap: 0
Slots in VTable: 7
--------------------------------------
MethodDesc Table
Entry MethodDesc JIT Name
79371278 7914b928 PreJIT System.Object.ToString()
7936b3b0 7914b930 PreJIT System.Object.Equals(System.Object)
7936b3d0 7914b948 PreJIT System.Object.GetHashCode()
793624d0 7914b950 PreJIT System.Object.Finalize()
00db0070 00a83020 JIT MyApp.Program.Main(System.String[])
00db0110 00a83028 JIT MyApp.Program.Test
(System.String)
00db00e0 00a83030 JIT MyApp.Program..ctor()
步骤四:获取Test方法的执行地址:
0:000> !dumpmd 00a83028
Method Name: MyApp.Program.ShowParams(Int32, System.String, Char)
Class: 00a811d8
MethodTable: 00a83038
mdToken: 06000002
Module: 00a82c3c
IsJitted: yes
m_CodeOrIL: 00db0110
步骤五:增加断点
0:000> bp 00db0110
也可以用BPMD命令在这个方法的MethodDesc上面下断点:
0:000> !bpmd -md 00a83028
MethodDesc = 00a83028
Setting breakpoint: bp 00DB0110 [MyApp.Program.Test(System.String)]
步骤六:继续调试
0:000>g
步骤七:单步调试:F10.
步骤八:查看参数信息。运行下面指令,获取到Test方法的的Data参数地址,!do查看即可。
0:000> !clrstack -a
完工!