通过SOS调查CLR

时间:2014-06-22 11:20:31

标签: c# .net clr

目前我正在深入研究CLR并尝试找到适当大小的托管对象。

我有两种简单的类型:

XClass

    class XClass
{
    public XStruct StructField = new XStruct();
    public int IntField;
    public double DoubleField;
}

XStruct

struct XStruct
{
    public short ShortField;
    public long LongField;
}

还涉及此对象的cosider代码段:

static unsafe void Main(string[] args)
{
    double angle = 0.34;

    {
        double anotherDouble = 1.49;

        XStruct xStruct = new XStruct();
        xStruct.ShortField = 12;
        xStruct.LongField = 1234567890;

        XClass classObject = new XClass();
        classObject.DoubleField = angle + anotherDouble;
        classObject.IntField = 123;
        classObject.StructField = xStruct;

        <<<<<<<<BREAKPOINT>>>>>>>

        xStruct.ShortField = 3;
    }

    double* ptr = &angle;

    Console.WriteLine(*(ptr - 1));
    Console.ReadKey();
}

所以,我尝试将一些关于XStruct的信息放在堆栈中,但我找不到它。

!dso
PDB symbol for clr.dll not loaded
OS Thread Id: 0x1f94 (8084)
ESP/REG  Object   Name
0018EF1C 0260252c ConsoleApplication2.XClass
0018EF20 0260252c ConsoleApplication2.XClass
0018F290 0260252c ConsoleApplication2.XClass
0018F2C4 0260251c System.Object[]    (System.String[])
0018F2E0 0260252c ConsoleApplication2.XClass
0018F2E8 0260252c ConsoleApplication2.XClass
0018F30C 0260251c System.Object[]    (System.String[])
0018F3C0 0260251c System.Object[]    (System.String[])
0018F51C 0260251c System.Object[]    (System.String[])
0018F554 0260251c System.Object[]    (System.String[])
0018FA90 02601238 System.SharedStatics

请解释为什么ConsoleApplication2.XStruct未显示以及为什么ConsoleApplication2.XClass在堆栈中显示为对象的原因。我认为XClass(作为普通引用类型)应该放在堆中。或者我对!dso的理解可能不正确。

感谢。

1 个答案:

答案 0 :(得分:3)

!dso ==转储堆栈对象。专注于“对象”,结构不是对象。

SOS能够查找对象引用的唯一原因是它可以使用抖动在编译方法时生成的元数据。垃圾收集器在执行堆栈遍历以查找对象引用时使用此数据。您可以在this answer中详细了解相关信息。此元数据中缺少值类型值,GC不关心它们。

您可以通过创建结构的数组来推断结构的大小,从而使结构的第一个字段具有独特的值。使用VS调试器,Debug + Windows + Memory + Memory1查看数组,将变量名称放在Address字段中。您将结构值返回到数组头之后的十六进制转储中。请注意,结构大小取决于CLR版本和进程的位数,因此只能将此信息用作提示。