2010-10-13 8 views
6

Mam zrzut pamięci, którego używam do rozwiązywania problemów z klientem. To jest aplikacja .NET (C#). Problem z moją aplikacją polega na tym, że tworzonych jest zbyt wiele instancji danej klasy. Jest 6300 wystąpień tej klasy, gdy powinno być coś w rodzaju 20. Chcę przechodzić przez wszystkie te wystąpienia i wywoływać pole nazwy każdej z tych instancji. Czy jest jakiś łatwy sposób to zrobić w WinDbg/SOS?Sprawdzanie pola we wszystkich wystąpieniach zrzutów pamięci

wiem, że mogę używać! Dumpheap -type {typename}, aby znaleźć wszystkie wystąpienia tej klasy, ale nie jestem pewien, w jaki sposób mogę je wszystkie rozwinąć i wyświetlić pole jestem zainteresowany.

Odpowiedz

14

Możesz to zrobić za pomocą polecenia .foreach w Windbg.

Oto prosty przykład

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; 
     } 
    } 
} 

!dumpheap ma krótkie opcję, która będzie tylko zwrotnego adresu obiektu. Na przykład jestem diagnostycznych MT dla Program jest 00293858

!dumpheap -mt 00293858 -short 

Oto kod zrzucić wszystkie obiekty .foreach ($obj {!dumpheap -mt 00293858 -short}) {!do $obj} pomocą konstruktu foreach. Obiekt $ obj zostanie przypisany wraz z adresem obiektu. I tu jest wyjście próbki z pętli foreach

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 

Teraz, gdy mamy to, następnym krokiem jest, aby pole „test” w każdej instancji programu i Oto kod, aby to zrobić

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

Używam polecenia poi w pętli foreach. Z powyższego wyniku możemy się zmienna test jest w 4 offsetowego i to jest powód do korzystania poi(${$obj}+0x4) I tu jest wyjście próbki z powyższego 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 << 

I tu jest coraz każde wystąpienie Foo zasięgu klasa Program

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

Foo jest w 8. offsetowego i tu jest próbka wyjścia dla powyższej foreach

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: - Również o to post z Tess na dumping zawartość sesji

HTH

+0

Jest to idealny !! Dzięki za wspaniałą odpowiedź. Teraz na prawdziwy problem z ustaleniem mojej aplikacji :) – Bryan

+0

Tak, znalazłem post Tess po tym, jak zadałem pytanie. – Bryan

+0

doskonałe wyjaśnienie! Dziękuję za szczegóły :) –

Powiązane problemy