.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(intView Codex, 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、執行 !clrstach –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
.net 高級調試學習(2)對象查看