ヒープ上のかなり深いオブジェクト グラフの対話型ビューを表示できるようにするだけでなく、多くの統計情報を取得しようとしているマネージド プロセスの非常に大きなメモリ ダンプがいくつかあります。SOS を使用した WinDbg の set に相当するものを考えてみて!do <address>
くださいprefer_dml 1
。プロパティを継続的にクリックしてその値を確認できますが、多くのオブジェクトを比較するためのはるかに使いやすい UI でのみ可能です。
Microsoft.Diagnostics.Runtime (ClrMD) がこのタスクに特に適していることがわかりましたが、配列フィールドの操作に苦労しており、オブジェクト フィールドについて少し混乱しています。より良い。
Array : ヒープから直接アドレスを指定して配列をターゲットにして使用するClrType.GetArrayLength
とClrType.GetArrayElementValue
問題なく動作しますが、別のオブジェクトのフィールドを掘り下げるとClrInstanceField.GetValue
、ClrInstanceField.ElementType
がClrElementType.SZArray
(オブジェクト グラフを掘り下げることはArray
まだありませんが、同様に処理したいと考えています)。
編集:ClrType
for使用しSystem.UInt64
て配列フィールドを逆参照するparent address + offset of the array field
た (配列ポインターが格納されているアドレスを計算するために使用します)。その後、EnumerateObjects から取得した場合と同じように操作できます。プロパティをサポートしていない一部の配列で問題が発生していArrayComponentType
ます。私はまだ構造体の配列でテストしていないので、それがインライン構造体のCスタイルの割り当てにint[]
なるのか、それともヒープ上の構造体へのポインターの配列になるのか疑問に思っています. Guid[]
からの取得に問題があるタイプの1つですArrayComponentType
。
オブジェクト:修正
(論理エラー) まず、呼び出した後、問題なく使用できるアドレス (?)が返されるので、ネストされたオブジェクトのフィールド名と値を確認できます。とはいえ、ポリモーフィズムを考慮する必要があるため、同じアドレスで使用しようとしたところ、NULL または完全に間違ったものが返されました。最初のユース ケースではアドレスが機能するのに、2 番目のユース ケースでは機能しないのは奇妙に思えます。ClrInstanceField
Type
ClrElementType.Object
GetFieldValue
ulong
ClrInstanceField.Type.Fields
ClrHeap.GetObjectType
String : Fixed (回避策が見つかりました)
私の実際のプロジェクトでは既に SOS 付きの DbgEng を使用しているため、アドレスによって文字列の値を簡単に取得する別の方法がありますが、使用しようとしてClrInstanceField.GetFieldValue
文字列を返すことに成功したのは非常に奇妙に思えましたが、完全に不正確な結果 (奇妙な文字の束)。多分私はこれを間違っていますか?
編集:元のコードから LINQPad で実行される抽象化を抽出しました。ここに投稿するには少し長くなりますが、要点はすべてここにあります。コピー/貼り付け/リファクタリングのすべてからまだ少し面倒です。これらの問題を修正した後、最終的なソースを CodePlex または GitHub に投稿する可能性があります。
コード ベースはかなり大きく、プロジェクトに固有のものですが、どうしても必要な場合は、サンプル セットを抽出できる場合があります。つまり、ClrMD オブジェクトへのすべてのアクセスは非常に単純です。!dumpheap -stat
(ルート オブジェクトに対しては正常に機能する) などのSOS コマンドから初期アドレスを取得し、ClrHeap.GetTypeByName
orを使用しますClrHeap.GetObjectType
。その後は、メンバー、、およびClrType.Fields
のみに依存します。ClrInstanceField
Type
ElementType
GetFieldValue
おまけとして、NuGet パッケージで提供される XML ドキュメントのブラウザー フレンドリーバージョンを見つけましたが、これは IntelliSense が提供するドキュメントと同じものです。