前言
有时候我们需要看程序中运行情况怎么,如:某对象字段的具体值是多少等问题,我们就可以用调试工具找到答案。我们还是沿用前面的程序。原代码在文章低部。
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();
Comparer c = 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;
}
}
}