.net 高级调试学习(2)对象查看
调试的程序源代码如下:
using System; using System.Text; namespace Advanced.NET.Debugging.Chapter3 { public class ObjTypes { public struct Coordinate { public int xCord; public int yCord; public int zCord; public Coordinate(int x, int y, int z) { xCord = x; yCord = y; zCord = z; } } private Coordinate coordinate; int[] intArray = new int[] { 1, 2, 3, 4, 5 }; string[] strArray = new string[] {"Welcome", "to", "Advanced", ".NET", "Debugging"}; static void Main(string[] args) { Coordinate point= new Coordinate(100, 100, 100); Console.WriteLine("Press any key to continue (AddCoordinate)"); Console.ReadKey(); ObjTypes ob = new ObjTypes(); ob.AddCoordinate(point); Console.WriteLine("Press any key to continue (Arrays)"); Console.ReadKey(); ob.PrintArrays(); Console.WriteLine("Press any key to continue (Generics)"); Console.ReadKey(); Comparer<int> c = new Comparer<int>(); Console.WriteLine("Greater {0}", c.GreaterThan(5, 10)); Console.WriteLine("Press any key to continue (Exception)"); Console.ReadKey(); ob.ThrowException(null); } public void AddCoordinate(Coordinate coord) { coordinate.xCord += coord.xCord; coordinate.yCord += coord.yCord; coordinate.zCord += coord.zCord; Console.WriteLine("x:{0}, y:{1}, z:{2}", coordinate.xCord, coordinate.yCord, coordinate.xCord); } public void PrintArrays() { foreach (int i in intArray) { Console.WriteLine("Int: {0}", i); } foreach (string s in strArray) { Console.WriteLine("Str: {0}", s); } } public void ThrowException(ObjTypes obj) { if (obj == null) { throw new System.ArgumentException("Obj cannot be null"); } } } public class Comparer<T> where T: IComparable { public T GreaterThan(T d, T d2) { int ret = d.CompareTo(d2); if (ret > 0) return d; else return d2; } public T LessThan(T d, T d2) { int ret = d.CompareTo(d2); if (ret < 0) return d; else return d2; } } }
上面代码使用.net 4编译出可执行exe
具体调试步骤如下:
1、在wdb中执行03ObjTypes.exe程序
2、执行g,运行到提示按任意键继续
3、在windbg手动中断程序
4、执行.loadby sos.dll clr
5、执行 ~0s 切换到主线程
6、执行 !name2ee 03ObjTypes.exe Advanced.NET.Debugging.Chapter3.ObjTypes.AddCoordinate
显示如下结果:
Module: 000007fe8eb140c0 Assembly: 03ObjTypes.exe Token: 0000000006000002 MethodDesc: 000007fe8eb15a00 Name: Advanced.NET.Debugging.Chapter3.ObjTypes.AddCoordinate(Coordinate) Not JITTED yet. Use !bpmd -md 000007fe8eb15a00 to break on run.
7. 执行 !bpmd -md 000007fe8eb15a00 设置断点
8、执行g 使程序继续执行,并且在程序中按任意键,此时程序中断在我们设断点位置
9、执行 !clrstack -a 查看调用栈
OS Thread Id: 0x1598 (0) Child SP IP Call Site 000000000023eaa0 000007fe8ec2089e *** WARNING: Unable to verify checksum for 03ObjTypes.exe Advanced.NET.Debugging.Chapter3.ObjTypes.AddCoordinate(Coordinate) [F:\book and sources\adndsrc\Chapter3\ObjTypes\03ObjTypes.cs @ 54] PARAMETERS: this (0x000000000023eb30) = 0x00000000027e6cd8 coord (0x000000000023eb98) = 0x0000006400000064 000000000023eb30 000007fe8ec2054b Advanced.NET.Debugging.Chapter3.ObjTypes.Main(System.String[]) [F:\book and sources\adndsrc\Chapter3\ObjTypes\03ObjTypes.cs @ 37] PARAMETERS: args (0x000000000023ec20) = 0x00000000027e3470 LOCALS: 0x000000000023ebf0 = 0x0000006400000064 0x000000000023eb90 = 0x00000000027e6cd8 0x000000000023eb88 = 0x0000000000000000 000000000023ee50 000007feee254073 [GCFrame: 000000000023ee50]
10、看到Main函数的locals中有三个局部变量(第三个还未 赋值),
可以使用!dumpobj 0x000000000023ebf0 查看第一个变量,显示错误,说明他是个值类型
<Note: this object has an invalid CLASS field>
执行 dd 0x000000000023ebf0 显示值类型的内容如下
00000000`0023ebf0 00000064 00000064 00000064 00000000 00000000`0023ec00 0023ed08 00000000 0023ee50 00000000 00000000`0023ec10 0023ec40 00000000 ee254073 000007fe 00000000`0023ec20 027e3470 00000000 8eb140c0 000007fe 00000000`0023ec30 00000000 00000000 00000000 00000000 00000000`0023ec40 0023ed30 00000000 0043a0f0 00000000 00000000`0023ec50 00000000 00000000 ee253f25 000007fe 00000000`0023ec60 0023ef08 00000000 ee2e38f1 000007fe
前三个值0x64就是值100,就是对应于代码 Coordinate point= new Coordinate(100, 100, 100);
在ClrStack命令输出中 AddCoordinate栈显示的this参数指针指向当前对象的实例,引用类型使用
!dumpobj 0x00000000027e6cd8 显示如下:
Name: Advanced.NET.Debugging.Chapter3.ObjTypes MethodTable: 000007fe8eb15b28 EEClass: 000007fe8eb126c8 Size: 48(0x30) bytes File: C:\ADNDBin 4\03ObjTypes.exe Fields: MT Field Offset Type VT Attr Value Name 000007fe8eb15a98 4000001 18 ...jTypes+Coordinate 1 instance 00000000027e6cf0 coordinate 000007feed2daf08 4000002 8 System.Int32[] 0 instance 00000000027e6dd8 intArray 000007feed2d9890 4000003 10 System.String[] 0 instance 00000000027e6e50 strArray
VT列 1表示值类型,0表示引用类型
对于值类型,执行 !dumpvc mt vale可以得到具体的值:
执行 !dumpvc 000007fe8eb15a98 00000000027e6cf0 可以得到coordinate的具体的值:
Name: Advanced.NET.Debugging.Chapter3.ObjTypes+Coordinate MethodTable: 000007fe8eb15a98 EEClass: 000007fe8eb12740 Size: 32(0x20) bytes File: C:\ADNDBin 4\03ObjTypes.exe Fields: MT Field Offset Type VT Attr Value Name 000007feed2daf70 4000005 0 System.Int32 1 instance 0 xCord 000007feed2daf70 4000006 4 System.Int32 1 instance 0 yCord 000007feed2daf70 4000007 8 System.Int32 1 instance 0 zCord
可以看到,coordinate的 x,y,z 都为0
对于引用类型
000007feed2daf08 4000002 8 System.Int32[] 0 instance 00000000027e6dd8 intArray
执行 !DumpObj /d 00000000027e6dd8显示
Name: System.Int32[] MethodTable: 000007feed2daf08 EEClass: 000007feecce2e90 Size: 44(0x2c) bytes Array: Rank 1, Number of elements 5, Type Int32 (Print Array) Fields: None
显示更具体的数组信息可以执行!DumpArray -details 00000000027e6dd8
Name: System.Int32[] MethodTable: 000007feed2daf08 EEClass: 000007feecce2e90 Size: 44(0x2c) bytes Array: Rank 1, Number of elements 5, Type Int32 Element Methodtable: 000007feed2daf70 [0] 00000000027e6de8 Name: System.Int32 MethodTable: 000007feed2daf70 EEClass: 000007feecce2e20 Size: 24(0x18) bytes File: C:\windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll Fields: MT Field Offset Type VT Attr Value Name 000007feed2daf70 400055f 0 System.Int32 1 instance 1 m_value [1] 00000000027e6dec Name: System.Int32 MethodTable: 000007feed2daf70 EEClass: 000007feecce2e20 Size: 24(0x18) bytes File: C:\windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll Fields: MT Field Offset Type VT Attr Value Name 000007feed2daf70 400055f 0 System.Int32 1 instance 2 m_value [2] 00000000027e6df0 Name: System.Int32 MethodTable: 000007feed2daf70 EEClass: 000007feecce2e20 Size: 24(0x18) bytes File: C:\windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll Fields: MT Field Offset Type VT Attr Value Name 000007feed2daf70 400055f 0 System.Int32 1 instance 3 m_value [3] 00000000027e6df4 Name: System.Int32 MethodTable: 000007feed2daf70 EEClass: 000007feecce2e20 Size: 24(0x18) bytes File: C:\windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll Fields: MT Field Offset Type VT Attr Value Name 000007feed2daf70 400055f 0 System.Int32 1 instance 4 m_value [4] 00000000027e6df8 Name: System.Int32 MethodTable: 000007feed2daf70 EEClass: 000007feecce2e20 Size: 24(0x18) bytes File: C:\windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll Fields: MT Field Offset Type VT Attr Value Name 000007feed2daf70 400055f 0 System.Int32 1 instance 5 m_value
可以看到value列 就是数组的值1 2 3 4 5
如果对数组的指针进行转储命令,执行dd 00000000027e6dd8显示如下
00000000`027e6dd8 ed2daf08 000007fe 00000005 00000000
00000000`027e6de8 00000001 00000002 00000003 00000004
00000000`027e6df8 00000005 00000000 00000000 00000000
00000000`027e6e08 ed2db0f0 000007fe 00000000 00000000
00000000`027e6e18 00000000 00000000 00000000 00000000
00000000`027e6e28 00000000 00000000 00000000 00000000
00000000`027e6e38 00000000 00000000 8eb15d70 000007fe
00000000`027e6e48 00000000 00000000 ed2d9890 000007fe
在此实例中,第一二数值 ed2daf08 000007fe 数组类型本身的方法表,
对于值类型数组,第三四值 00000005 00000000就是数组大小,后面就是数组内容
00000001 00000002 00000003 00000004 00000000`027e6df8 00000005
PS :书中的例子说的是 对于数值数组,第一数值是数组方法表,第二数值是数组大小,后面是数组内容,
还有对于引用类型数组,第一数值是方法表,第二数值是数组大小,第三数值是数组元素的方法表,后面才是数组内容
,但我这例子中不一样,不知是否与x64、 x86程序还是.net4 或.net2不同有关。下面看到的引用类型数组也是和我上面说的例子是一样的:第一数值是数组方法表,第二数值是数组大小,后面是数组内容
下面对
000007feed2d9890 4000003 10 System.String[] 0 instance 00000000027e6e50 strArray
执行 !DumpArray -details 00000000027e6e50 可以看到sting[]数组的内容如下:
Name: System.String[] MethodTable: 000007feed2d9890 EEClass: 000007feecce24a8 Size: 64(0x40) bytes Array: Rank 1, Number of elements 5, Type CLASS Element Methodtable: 000007feed2d8548 [0] 00000000027e6d08 Name: System.String MethodTable: 000007feed2d8548 EEClass: 000007feecc24ab8 Size: 40(0x28) bytes File: C:\windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: Welcome Fields: MT Field Offset Type VT Attr Value Name 000007feed2daf70 4000243 8 System.Int32 1 instance 7 m_stringLength 000007feed2d96f8 4000244 c System.Char 1 instance 57 m_firstChar 000007feed2d8548 4000248 80 System.String 0 shared static Empty >> Domain:Value 00000000003e7860:NotInit << [1] 00000000027e6d30 Name: System.String MethodTable: 000007feed2d8548 EEClass: 000007feecc24ab8 Size: 30(0x1e) bytes File: C:\windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: to Fields: MT Field Offset Type VT Attr Value Name 000007feed2daf70 4000243 8 System.Int32 1 instance 2 m_stringLength 000007feed2d96f8 4000244 c System.Char 1 instance 74 m_firstChar 000007feed2d8548 4000248 80 System.String 0 shared static Empty >> Domain:Value 00000000003e7860:NotInit << [2] 00000000027e6d50 Name: System.String MethodTable: 000007feed2d8548 EEClass: 000007feecc24ab8 Size: 42(0x2a) bytes File: C:\windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: Advanced Fields: MT Field Offset Type VT Attr Value Name 000007feed2daf70 4000243 8 System.Int32 1 instance 8 m_stringLength 000007feed2d96f8 4000244 c System.Char 1 instance 41 m_firstChar 000007feed2d8548 4000248 80 System.String 0 shared static Empty >> Domain:Value 00000000003e7860:NotInit << [3] 00000000027e6d80 Name: System.String MethodTable: 000007feed2d8548 EEClass: 000007feecc24ab8 Size: 34(0x22) bytes File: C:\windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: .NET Fields: MT Field Offset Type VT Attr Value Name 000007feed2daf70 4000243 8 System.Int32 1 instance 4 m_stringLength 000007feed2d96f8 4000244 c System.Char 1 instance 2e m_firstChar 000007feed2d8548 4000248 80 System.String 0 shared static Empty >> Domain:Value 00000000003e7860:NotInit << [4] 00000000027e6da8 Name: System.String MethodTable: 000007feed2d8548 EEClass: 000007feecc24ab8 Size: 44(0x2c) bytes File: C:\windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: Debugging Fields: MT Field Offset Type VT Attr Value Name 000007feed2daf70 4000243 8 System.Int32 1 instance 9 m_stringLength 000007feed2d96f8 4000244 c System.Char 1 instance 44 m_firstChar 000007feed2d8548 4000248 80 System.String 0 shared static Empty >> Domain:Value 00000000003e7860:NotInit <<
看到输出的string 行,上面红色标的就是字符串的值
执行dd 00000000027e6e50
可以看到
00000000`027e6e50 ed2d9890 000007fe 00000005 00000000 00000000`027e6e60 027e6d08 00000000 027e6d30 00000000 00000000`027e6e70 027e6d50 00000000 027e6d80 00000000 00000000`027e6e80 027e6da8 00000000 00000000 80000000 00000000`027e6e90 ed2d8548 000007fe 00000013 003a0078 00000000`027e6ea0 0030007b 002c007d 00790020 007b003a 00000000`027e6eb0 007d0031 0020002c 003a007a 0032007b 00000000`027e6ec0 0000007d 00000000 00000000 00000000
作者:碎心炼心
出处:http://www.cnblogs.com/karl-F
本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。