3

簡単な 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

私が得た出力は明らかに間違っていました (フィールドはすべてめちゃくちゃです。「現在」の下に「インデックス」の値、「バージョン」の下に「現在」の値、「インデックス」の下にバージョンの値が報告されているようです。 '. 正しいフィールドは 1 つだけです - 最初のフィールドです。

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

なぜこれが起こるのですか?

4

1 に答える 1

3

問題は、CLR がクローズ型 (int の列挙子) の列挙子構造体のフィールドを並べ替えたため、オープン型 (T の列挙子) と一致しないことです。Sosex は、クローズド タイプの代わりにオープン タイプを使用してフィールドを読み取っていました。sosex のこのバグは修正されました。

于 2014-02-06T21:46:54.177 に答える