Почему SOS/SOSEx неправильно интерпретирует значения System.Collections.Generic.List.Enumerator?

Я написал простое приложение на C#:

   static void Main(string[] args)
    {
       var list = new List<int> {500,400,300,200,100};
       var listEnumerator = list.GetEnumerator();
       listEnumerator.MoveNext();
    }  // <--- breakpoint here

Я поставил точку останова в конце, запустил ее с помощью Visual Studio, затем запустил windbg и подключил к процессу (с включенным флажком "неинвазивный").

Затем я ввел эти команды:

.load C:\Program Files (x86)\Windows Kits\8.0\Debuggers\x86\sosex.dll
!mframe 17
!mdt listEnumerator

Вывод, который я получил, был явно неправильным (все поля перепутаны, кажется, что он сообщает значение 'index' в 'current', значение 'current' в 'version' и значение version 'в' index ' '. Он получил только одно поле - первое.

Local #0: (System.Collections.Generic.List`1+Enumerator) VALTYPE (MT=72dfd838, ADDR=0029efb8)
    list:02632464 (System.Collections.Generic.List`1[[System.Int32, mscorlib]])
    index:0x5 (System.Int32)
    version:0x1f4 (System.Int32)
    current:00000001 (T)

Затем я попытался использовать SOS!DumpVC, и получил ту же путаницу:

    0:000> !DumpVC 72dfd838 0029efb8
Name:        System.Collections.Generic.List`1+Enumerator
MethodTable: 72dfd838
EEClass:     72a32d38
Size:        24(0x18) bytes
File:        C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
736ae16c  4000c99        0 ...Generic.List`1[T]  0 instance 02632464 list
72e03aa4  4000c9a        8         System.Int32  1 instance        5 index
72e03aa4  4000c9b        c         System.Int32  1 instance      500 version
00000000  4000c9c        4                  VAR  0 instance 00000001 current

Почему это происходит?

1 ответ

Проблема в том, что CLR переупорядочил поля структуры перечислителя для закрытого типа (перечислитель типа int), чтобы они не соответствовали открытому типу (перечислитель типа T). Sosex использовал открытый тип для чтения полей вместо закрытого типа. Эта ошибка в sosex теперь исправлена.

Другие вопросы по тегам