前言
有时候我们需要看程序中运行情况怎么,如:某对象字段的具体值是多少等问题,我们就可以用调试工具找到答案。我们还是沿用前面的程序。原代码在文章低部。
dump栈上的值
在线程4中输入!ClrStack -a结果说该线程不是托管线程,于是我们用~0s 转到主线程,在输入该命令,他的调用栈相关信息就已经出来了,如下面所示:
在Main方法中有2个变量
此时我们用得!do得到它的值,结果显示说他不是一个类字段,那说明他是一个值类型,我们用dd命令发现在栈上果然有3个值分别是0x64,转成10进制那就是100。
dump堆上的对象
如果值类型包含在类中那么他会保存在堆上。要看堆中有那些对象,可以用!dumpheap 命令。然而堆上的对象非常多,我们一般可以在!dumpheap增加一个-type 来查找堆中的指定类型。如下图所示:
通过该命令我们就得到了,ObjTypes的对象的地址:00000000027eab68
当然!dumpheap 还有其它参考具体如下:
!dumpheap:dump堆中的所有对象
!dumpheap -type <类型,包括命名空间> :dump堆中的指定对象
!dumpheap -mt <方法表地址> :dump堆中的指定对象
!dumpheap -min <最小内存大小> :dump堆中大于指定内存的对象
!dumpheap -startAtLowerBound <开始地址> 显示该地址块中有那些对象。
!dumpheap -thinlock:查看堆上所有瘦锁对象
!dumpheap -stat 统计堆中各对象的个数,类型于sql中的group by
然后在调用!do命令,就会得到该实体的具体数据有那些,具体效果如下图所示:
我们可以看到改对象有3个字段,一个是Coordinate的值类型,注:VT=1说明是值类型。另外有二个数组类型分别是int和object数组类型。
dump值类型数据
查看值类型数据一般用!dumpvc <方法表地址> <值类型地址>; 导出值类型数据,结果如下:
我们发现ObjTypes中的Coordinate有定义了3个int类型分别是xCord、yCord、zCord 他们各自的值为100
dump数组中的数据
dump 数组中的数据,我们用 !da -details <数组地址>,结果如下:
同理,dump 字符串数组也是一样:
!da 也有一些相关参数可以设置,具体如下:
!da(!DumpArray)[-start <数组那个索引开始>] [-length<显示数组多少个元素>] [-details] [-nofields] 数据地址
[-details] 显示数组的详细信息,包括具体值。
[-nofields] 只显示内容不会显字符串类型中的各个域
示例代码
代码如下:
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(); Comparerc = new Comparer (); 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 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; } } }