2010-10-13 9 views
6

Ich habe einen Speicherabbild, den ich verwende, um ein Clientproblem zu beheben. Dies ist eine .NET (C#) Anwendung. Das Problem mit meiner Anwendung ist, dass zu viele Instanzen einer bestimmten Klasse erstellt werden. Es gibt 6300 Instanzen dieser Klasse, wenn es etwa 20 geben soll. Ich möchte alle diese Instanzen durchlaufen und das Namensfeld jeder dieser Instanzen aufrufen. Gibt es einen einfachen Weg, dies in WinDbg/SOS zu tun?Inspect-Feld für alle Instanzen im Speicherabbild

Ich weiß, dass ich benutzen kann! Dumpheap Typ {} Typname alle Instanzen dieser Klasse zu finden, aber ich bin nicht sicher, wie ich sie alle und sehen, das Feld erweitern, die mich interessiert.

Antwort

14

Sie können dies mit .foreach Befehl in Windbg tun.

Hier ist ein einfaches Beispiel

using System; 
using System.Collections.Generic; 
using System.Linq; 
namespace Test 
{ 
    class Program 
    { 
     static List<Program> list = new List<Program>(); 
     int i; 
     string test; 
     Foo f; 
     static void Main(string[] args) 
     { 
      for (int i = 0; i < 10; i++) 
      { 
       list.Add(new Program() { i = i, test = "Test" + i.ToString(), f = new Foo(i) }); 
      } 
      Console.Read(); 
     } 
    } 
    class Foo 
    { 
     int j; 
     public Foo(int i) 
     { 
      j = i; 
     } 
    } 
} 

Die !dumpheap eine kurze Option hat, die nur die Objektadresse zurückkehren würde. In der Instanz i MT für Program Debuggen sind, ist 00293858

!dumpheap -mt 00293858 -short 

Hier ist ein Code, um die Objekte all .foreach ($obj {!dumpheap -mt 00293858 -short}) {!do $obj} mit dem foreach-Konstrukt zu entleeren. Das $ obj würde mit der Adresse des Objekts zugewiesen werden. Und hier ist das Beispiel für die Ausgabe der foreach-Schleife

Name:  Test.Program 
MethodTable: 00293858 
EEClass:  00291440 
Size:  20(0x14) bytes 
File:  c:\users\nsrinivasan\documents\visual studio 2010\Projects\Test\Test\bin\Debug\Test.exe 
Fields: 
     MT Field Offset     Type VT  Attr Value Name 
5c2e2978 4000002  c   System.Int32 1 instance  3 i 
5c2df9ac 4000003  4  System.String 0 instance 0217c144 test 
00293bfc 4000004  8    Test.Foo 0 instance 0217c15c f 
002938b4 4000001  4 ...t.Program, Test]] 0 static 0217b97c list 
Name:  Test.Program 
MethodTable: 00293858 
EEClass:  00291440 
Size:  20(0x14) bytes 
File:  c:\users\nsrinivasan\documents\visual studio 2010\Projects\Test\Test\bin\Debug\Test.exe 
Fields: 
     MT Field Offset     Type VT  Attr Value Name 
5c2e2978 4000002  c   System.Int32 1 instance  4 i 
5c2df9ac 4000003  4  System.String 0 instance 0217c18c test 
00293bfc 4000004  8    Test.Foo 0 instance 0217c1a4 f 
002938b4 4000001  4 ...t.Program, Test]] 0 static 0217b97c list 

Jetzt, wo wir haben dies der nächste Schritt ist das Feld „Test“ in jedem Fall von Programm zu bekommen und hier ist der Code zu tun, dass

.foreach ($obj {!dumpheap -mt 00293858 -short}) {!do poi(${$obj}+0x4)} 

Ich verwende poi Befehl innerhalb der Foreach-Schleife. Aus dem obigen Ergebnis können wir die test Variable in den 4-Offset machen und das ist der Grund für die Verwendung von poi(${$obj}+0x4) Und hier sind die Beispielausgabe des oben foreach

0:004> .foreach ($obj {!dumpheap -mt 00293858  -short}) {!do poi(${$obj}+0x4)} 
Name:  System.String 
MethodTable: 5c2df9ac 
EEClass:  5c018bb0 
Size:  24(0x18) bytes 
File:  C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll 
String:  Test0 
Fields: 
     MT Field Offset     Type VT  Attr Value Name 
5c2e2978 40000ed  4   System.Int32 1 instance  5 m_stringLength 
5c2e1dc8 40000ee  8   System.Char 1 instance  54 m_firstChar 
5c2df9ac 40000ef  8  System.String 0 shared static Empty 
    >> Domain:Value 002f76c0:02171228 << 
Name:  System.String 
MethodTable: 5c2df9ac 
EEClass:  5c018bb0 
Size:  24(0x18) bytes 
File:  C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll 
String:  Test1 
Fields: 
     MT Field Offset     Type VT  Attr Value Name 
5c2e2978 40000ed  4   System.Int32 1 instance  5 m_stringLength 
5c2e1dc8 40000ee  8   System.Char 1 instance  54 m_firstChar 
5c2df9ac 40000ef  8  System.String 0 shared static Empty 
    >> Domain:Value 002f76c0:02171228 << 

Und hier sind für immer jede Foo Instanz innerhalb die Program Klasse

.foreach ($obj {!dumpheap -mt 00293858 -short}) {!do poi(${$obj}+0x8)} 

die Foo ist im 8. Offset- und hier ist die Ausgabe für die oben foreach Probe

Name:  Test.Foo 
MethodTable: 00293bfc 
EEClass:  0029194c 
Size:  12(0xc) bytes 
File:  c:\users\nsrinivasan\documents\visual studio 2010\Projects\Test\Test\bin\Debug\Test.exe 
Fields: 
     MT Field Offset     Type VT  Attr Value Name 
5c2e2978 4000005  4   System.Int32 1 instance  0 j 
Name:  Test.Foo 
MethodTable: 00293bfc 
EEClass:  0029194c 
Size:  12(0xc) bytes 
File:  c:\users\nsrinivasan\documents\visual studio 2010\Projects\Test\Test\bin\Debug\Test.exe 
Fields: 
     MT Field Offset     Type VT  Attr Value Name 
5c2e2978 4000005  4   System.Int32 1 instance  1 j 

EDIT: - Auch hier ist ein post von Tess auf Sitzung Inhalt

HTH

+0

Dies ist ideal Dumping !! Danke für die tolle Antwort. Jetzt auf das eigentliche Problem der Korrektur meiner Bewerbung :) – Bryan

+0

Ja, ich fand Tess Post nachdem ich die Frage gestellt. – Bryan

+0

ausgezeichnete Erklärung! Danke für das Detail :) –

Verwandte Themen