Pergunta

I created simple jagged array:

int[][] a = new int[2][];
for (int i = 0; i < 2; i++)
{
    a[i] = new int[3];
    for (int j = 0; j < 3; j++)
        a[i][j] = i * 3 + j;
}

After that I started debugging my application and looked to this array sturcture in memory (x86):

0x03022478           0  // SyncBlockIndex (a)
0x0302247C  0x61B8D5BC  // TypeHandle (a)
0x03022480           2  // a.Length
0x03022484  0x617A4C8A  // ???
0x03022488  0x03022494  // a[0]
0x0302248C  0x030224AC  // a[1]
0x03022490           0  // SyncBlockIndex (a[0])
0x03022494  0x61B9C448  // TypeHandle (a[0])
0x03022498           3  // a[0].Length
0x0302249C           0  // a[0][0]
0x030224A0           1  // a[0][1]
0x030224A4           2  // a[0][2]
0x030224A8           0  // SyncBlockIndex (a[1])
0x030224AC  0x61B9C448  // TypeHandle (a[1])
0x030224B0           3  // a[1].Length
0x030224B4           3  // a[1][0]
0x030224B8           4  // a[1][1]
0x030224BC           5  // a[1][2]

I understand almost all the data: SyncBlockIndexes, TypeHandles, Lengths, Elements. But I can't understand only one line:

0x03022484  0x617A4C8A  // ???

What it is?

Update 1:

I tried resolve this address value with different SOS command:

!DumpArray 0x617A4C8A
<Note: this object has an invalid CLASS field>
Invalid object

!DumpAssembly 0x617A4C8A
Fail to fill Assembly

!DumpClass 0x617A4C8A
Invalid EEClass address

!DumpDomain 0x617A4C8A
Fail to fill AppDomain

!DumpMD 0x617A4C8A
617a4c8a is not a MethodDesc

!DumpMT 0x617A4C8A  
617a4c8a is not a MethodTable

!DumpObj 0x617A4C8A 
<Note: this object has an invalid CLASS field>
Invalid object    

!DumpSig 0x617A4C8A
!DumpSig <sigaddr> <moduleaddr>

Update 2:

In array of references types this DWORD should mean address of array element MethodTable. For example, for object[10] this DWORD is address of MethodTable for System.Object. But in the case of int[][] this DWORD is not valid MethodTable address (I use SOS-command DumpMT for checking it).

Foi útil?

Solução

Quoting from the SSCLI source code (\sscli20_20060311\sscli20\clr\src\vm\object.h):

// ArrayBase encapuslates all of these details.  In theory you should never
// have to peek inside this abstraction
class ArrayBase : public Object
{
    ...
    // This MUST be the first field, so that it directly follows Object.  This is because
    // Object::GetSize() looks at m_NumComponents even though it may not be an array (the
    // values is shifted out if not an array, so it's ok). 
    DWORD       m_NumComponents;
    ...
    // What comes after this conceputally is:
    // TypeHandle elementType;        Only present if the method table is shared among many types (arrays of pointers)
    // INT32      bounds[rank];       The bounds are only present for Multidimensional arrays   
    // INT32      lowerBounds[rank];  Valid indexes are lowerBounds[i] <= index[i] < lowerBounds[i] + bounds[i]

The extra word you are seeing should be the TypeHandle elementType:

Only present if the method table is shared among many types (arrays of pointers)

\sscli20_20060311\sscli20\clr\src\vm\typehandle.h:

// At the present time a TypeHandle can point at two possible things
//
//      1) A MethodTable    (Intrinsics, Classes, Value Types and their instantiations)
//      2) A TypeDesc       (all other cases: arrays, byrefs, pointer types, function pointers, generic type variables) 

int[][] is array of int[], TypeHandle of int[] is TypeDesc. So, strange data is TypeHandle, but it can't resolved by !DumpMT because it's not a MethodTable.

The SSCLI is of course not the real Microsoft CLR implementation, but I understand it is a stripped down version of the 2.0 CLR.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top