

Windows调试学习笔记:(二)WinDBG调试.NET程序示例
source link: https://www.cnblogs.com/ceachy/p/WinDBG_Demo1.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Windows调试学习笔记:(二)WinDBG调试.NET程序示例
好不容易把环境打好了,一定要试试牛刀。我创建了一个极其简单的程序(如下)。让我们期待会有好的结果吧,阿门!
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { int a; string str; a = 5; str = a.ToString(); Console.WriteLine(str); } } }
默认编译成x86的输出代码,路径是E:\Projects\Practise\ConsoleApplication1\ConsoleApplication1\bin\Debug。然后就开始调试的步骤了:
1、加载调试程序
启动WinDBG以后,选择“文件-选择可执行文件。。。”,找到E:\Projects\Practise\ConsoleApplication1\ConsoleApplication1\bin\Debug目录下的ConsoleApplication1.exe文件,单击“打开”按钮。这样我们的调试目标程序已经打开了。
2、加载pdb文件
执行ld命令为ConsoleApplication1.exe程序集加载pdb文件:
0:000> ld ConsoleApplication1 *** WARNING: Unable to verify checksum for ConsoleApplication1.exe Symbols loaded for ConsoleApplication1
3、加载SOS
基于以往失败经验,我们一开始就使用SXE命令:
0:000> sxe ld:clrjit 0:000> g ... 0:000> .loadby sos clr
4、设置断点
我们是用BPMD命令设置断点如下:
0:000> !bpmd ConsoleApplication1.exe ConsoleApplication1.Program.Main Found 1 methods in module 00162ea4... MethodDesc = 001637f8 Adding pending breakpoints...
5、检查断点是否停下来
输入g让被调试程序继续执行,如果在断点位置停下来了,就会显示如下结果:
0:000> g (6164.4fe0): CLR notification exception - code e0444143 (first chance) JITTED ConsoleApplication1!ConsoleApplication1.Program.Main(System.String[]) Setting breakpoint: bp 00210070 [ConsoleApplication1.Program.Main(System.String[])] Breakpoint 0 hit eax=001637f8 ebx=00000000 ecx=0265ba00 edx=0035f150 esi=0060c7e0 edi=0035f0a0 eip=00210070 esp=0035f078 ebp=0035f084 iopl=0 nv up ei pl nz ac pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000216 00210070 55 push ebp
6、检查堆栈
使用!clrstack命令检查堆栈,记得加上-a参数:
0:000> !clrstack -a OS Thread Id: 0x4fe0 (0) Child SP IP Call Site 0035f078 00210070 ConsoleApplication1.Program.Main(System.String[]) [E:\Projects\Practise\ConsoleApplication1\ConsoleApplication1\Program.cs @ 11] PARAMETERS: args (<CLR reg>) = 0x0265ba00 LOCALS: <no data> <no data> 0035f2a0 5dc321bb [GCFrame: 0035f2a0]
这里已经能够看到Main函数内部的一些情况了,比如args的地址。但是我们想看的a和str却还没有。这又两个原因:1、它们不会显示名字;2、它们还没有被定义。
7、单步执行
不断输入p命令往下执行,并且不断地检查堆栈情况。我输入9次以后出现了以下结果:
0:000> p eax=00000000 ebx=00000000 ecx=0265ba00 edx=00000000 esi=0060c7e0 edi=0035f0a0 eip=00210091 esp=0035f064 ebp=0035f074 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246 00210091 90 nop 0:000> !clrstack -a OS Thread Id: 0x4fe0 (0) Child SP IP Call Site 0035f064 00210091 ConsoleApplication1.Program.Main(System.String[]) [E:\Projects\Practise\ConsoleApplication1\ConsoleApplication1\Program.cs @ 11] PARAMETERS: args (0x0035f070) = 0x0265ba00 LOCALS: 0x0035f06c = 0x00000000 0x0035f068 = 0x00000000 0035f2a0 5dc321bb [GCFrame: 0035f2a0]
这里LOCALS:下面的两个就是a和str,但是它们下载还是没有值。又执行2次p命令以后,a的值已经显示出来了:
0:000> !clrstack -a OS Thread Id: 0x4fe0 (0) Child SP IP Call Site 0035f064 00210099 ConsoleApplication1.Program.Main(System.String[]) [E:\Projects\Practise\ConsoleApplication1\ConsoleApplication1\Program.cs @ 16] PARAMETERS: args (0x0035f070) = 0x0265ba00 LOCALS: 0x0035f06c = 0x00000005 0x0035f068 = 0x00000000 0035f2a0 5dc321bb [GCFrame: 0035f2a0]
继续执行5次p命令之后,str的地址也显示出来了:
0:000> !clrstack -a OS Thread Id: 0x4fe0 (0) Child SP IP Call Site 0035f064 002100aa ConsoleApplication1.Program.Main(System.String[]) [E:\Projects\Practise\ConsoleApplication1\ConsoleApplication1\Program.cs @ 18] PARAMETERS: args (0x0035f070) = 0x0265ba00 LOCALS: 0x0035f06c = 0x00000005 0x0035f068 = 0x0265c06c 0035f2a0 5dc321bb [GCFrame: 0035f2a0]
8、查看引用类型成员
str的地址显示出来以后,我们就可以使用!dumpobj命令来查看它的值以及其他信息了:
0:000> !dumpobj 0x0265c06c Name: System.String MethodTable: 5d17fba0 EEClass: 5ceb8bb0 Size: 16(0x10) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: 5 Fields: MT Field Offset Type VT Attr Value Name 5d182b6c 4000103 4 System.Int32 1 instance 1 m_stringLength 5d181fbc 4000104 8 System.Char 1 instance 35 m_firstChar 5d17fba0 4000105 8 System.String 0 shared static Empty >> Domain:Value 005d4d00:02651228 <<
从中我们看到字符串的值为"5",它的长度是1等等。
这里记录的过于详细了。但如果是初学的话,能够亦步亦趋的把第一个程序“成功的”练习一下,也是莫大的成功;任何一步失败,都可能让你前功尽弃。Good Luck!
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK