I would like to run !refs command against each address from following command
!dumpgen 2 -type System.DateTime[]
How this could be done.I know a loop can be created as follows
.foreach (myvar {!dumpgen 2 -type System.DateTime[]})
But how can I access object address that could be used in loop with !refs?
!dumpgen
does not have a -short
argument like !dumpheap
has and I'd really like to see a simpler answer than this one.
Get the addresses of the heap
0:003> !eeheap -gc
Number of GC Heaps: 1
generation 0 starts at 0x026f1018
generation 1 starts at 0x026f100c
generation 2 starts at 0x026f1000
Use the addresses to limit the output to the generation you want:
!dumpheap -type X <start> <end>
Use the -short
parameter on !dumpheap
, which outputs the address only. This address of an object can then be processed by other commands.
Also note: using -type
may result in other types as well. Better use the method table with -mt
since only that guarantees the uniqueness of types. Use !name2ee
if you don't get that from elsewhere.
A complete session could look like this:
0:003> !dumpheap -stat
total 345 objects
Statistics:
MT Count TotalSize Class Name
53ab421c 1 12 System.Text.DecoderExceptionFallback
[...]
53ab0d48 135 6640 System.String
53a84518 26 9452 System.Object[]
Total 345 objects
0:003> !eeheap -gc
Number of GC Heaps: 1
generation 0 starts at 0x026f1018
generation 1 starts at 0x026f100c
generation 2 starts at 0x026f1000
[...]
0:003> !name2ee *!System.String
Module: 53841000 (mscorlib.dll)
Token: 0x02000024
MethodTable: 53ab0d48
[...]
0:003> !dumpheap -short -mt 53ab0d48 0x026f1000 0x026f100c
(Ok, all my strings seem to be in generation 0, damn :-)
0:003> .foreach (addr {!dumpheap -short -mt 53ab0d48 0x026f1018}) {!refs ${addr}}
Disadvantage: you need to do that for all GC heaps separately. There could be several of them.
Another ugly solution is to
!dumpheap -short
and -type
or -mt
)!gcgen
Here's how to do it (formatted for readability, put it all into one line):
.foreach (addr {!dumpheap -short -mt 53ab0d48}) {
.foreach /pS 1 (gen {!gcgen ${addr}}) {
.if ($scmp("${gen}","2")==0) {
!refs ${addr}
}
}
}
where 53ab0d48
is the method table of the type you're looking for and "2"
is the generation you want. /pS 1
skips the word "Gen" in the output of !gcgen
.
Disadvantage: might be slow since it works on all objects.