.NET 调试入门(二) dump 出程序数据

前言

         有时候我们需要看程序中运行情况怎么,如:某对象字段的具体值是多少等问题,我们就可以用调试工具找到答案。我们还是沿用前面的程序。原代码在文章低部。

dump栈上的值

在线程4中输入!ClrStack -a结果说该线程不是托管线程,于是我们用~0s 转到主线程,在输入该命令,他的调用栈相关信息就已经出来了,如下面所示:

image

在Main方法中有2个变量

此时我们用得!do得到它的值,结果显示说他不是一个类字段,那说明他是一个值类型,我们用dd命令发现在栈上果然有3个值分别是0x64,转成10进制那就是100。

image 

dump堆上的对象

如果值类型包含在类中那么他会保存在堆上。要看堆中有那些对象,可以用!dumpheap 命令。然而堆上的对象非常多,我们一般可以在!dumpheap增加一个-type  来查找堆中的指定类型。如下图所示:

image

通过该命令我们就得到了,ObjTypes的对象的地址:00000000027eab68

当然!dumpheap 还有其它参考具体如下:

!dumpheap:dump堆中的所有对象
!dumpheap -type <类型,包括命名空间> :dump堆中的指定对象
!dumpheap -mt <方法表地址> :dump堆中的指定对象
!dumpheap -min <最小内存大小> :dump堆中大于指定内存的对象
!dumpheap -startAtLowerBound <开始地址> 显示该地址块中有那些对象。
!dumpheap -thinlock:查看堆上所有瘦锁对象
!dumpheap -stat 统计堆中各对象的个数,类型于sql中的group by

然后在调用!do命令,就会得到该实体的具体数据有那些,具体效果如下图所示:

image

我们可以看到改对象有3个字段,一个是Coordinate的值类型,注:VT=1说明是值类型。另外有二个数组类型分别是int和object数组类型。

dump值类型数据

查看值类型数据一般用!dumpvc <方法表地址> <值类型地址>; 导出值类型数据,结果如下:

image

我们发现ObjTypes中的Coordinate有定义了3个int类型分别是xCord、yCord、zCord 他们各自的值为100

dump数组中的数据

dump 数组中的数据,我们用 !da -details <数组地址>,结果如下:

image

同理,dump 字符串数组也是一样:

image

!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;
        }
    }
}
作者: 吉桂昕
出处: http://www.cnblogs.com/jiguixin
我的新浪微博: http://weibo.com/jiguixin
本文版权归【吉桂昕】和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。
原文地址:https://www.cnblogs.com/jiguixin/p/3147683.html