Add generation option to dumpheap command (#3966)
authorIgor Bagdamyan <37334640+En3Tho@users.noreply.github.com>
Mon, 12 Jun 2023 20:38:17 +0000 (23:38 +0300)
committerGitHub <noreply@github.com>
Mon, 12 Jun 2023 20:38:17 +0000 (13:38 -0700)
This is a very small change to address https://github.com/dotnet/diagnostics/issues/3963

Few questions:
1) Should I add tests for this?
2) I've asked about GCGeneration custom type that is a clone of
Generation "official" type in that issue. It is a part of dumpgen
command which itself, after this change, kinda loses it's meaning. I
think the way forward is just to either remove dumpgen command or leave
it as a proxy for dumpheap.

src/Microsoft.Diagnostics.ExtensionCommands/DumpHeapCommand.cs
src/Microsoft.Diagnostics.ExtensionCommands/HeapWithFilters.cs
src/SOS/SOS.UnitTests/Scripts/GCPOH.script
src/SOS/SOS.UnitTests/Scripts/GCTests.script

index 2f8c47256b3ee8f566265e1735260161d73c3901..5f2faf6549357c87339e3ba4635428dbafae2609 100644 (file)
@@ -62,6 +62,9 @@ namespace Microsoft.Diagnostics.ExtensionCommands
         [Option(Name = "-thinlock")]
         public bool ThinLock { get; set; }
 
+        [Option(Name = "-gen")]
+        public string Generation { get; set; }
+
         [Argument(Help = "Optional memory ranges in the form of: [Start [End]]")]
         public string[] MemoryRange { get; set; }
 
@@ -227,6 +230,22 @@ namespace Microsoft.Diagnostics.ExtensionCommands
                 MethodTable = Runtime.Heap.StringType.MethodTable;
             }
 
+            if (!string.IsNullOrWhiteSpace(Generation))
+            {
+                Generation generation = Generation.ToLowerInvariant() switch
+                {
+                    "gen0" => Diagnostics.Runtime.Generation.Generation0,
+                    "gen1" => Diagnostics.Runtime.Generation.Generation1,
+                    "gen2" => Diagnostics.Runtime.Generation.Generation2,
+                    "loh" or "large" => Diagnostics.Runtime.Generation.Large,
+                    "poh" or "pinned" => Diagnostics.Runtime.Generation.Pinned,
+                    "foh" or "frozen" => Diagnostics.Runtime.Generation.Frozen,
+                    _ => throw new ArgumentException($"Unknown generation: {Generation}. Only gen0, gen1, gen2, loh (large), poh (pinned) and foh (frozen) are supported")
+                };
+
+                FilteredHeap.Generation = generation;
+            }
+
             FilteredHeap.SortSegments = (seg) => seg.OrderBy(seg => seg.Start);
         }
     }
index 7c5604e6b153c89d678d2054ad56ccec2b4187f7..b8abc377828c2ab0ce00219cd12f31eb89ff48c1 100644 (file)
@@ -63,6 +63,11 @@ namespace Microsoft.Diagnostics.ExtensionCommands
         /// </summary>
         public ulong MaximumObjectSize { get; set; }
 
+        /// <summary>
+        /// Only enumerate object from this generation
+        /// </summary>
+        public Generation? Generation { get; set; }
+
         /// <summary>
         /// The order in which to enumerate segments.  This also applies to object enumeration.
         /// </summary>
@@ -228,6 +233,11 @@ namespace Microsoft.Diagnostics.ExtensionCommands
                     objs = segment.EnumerateObjects(carefully: true);
                 }
 
+                if (Generation is Generation generation)
+                {
+                    objs = objs.Where(obj => segment.GetGeneration(obj) == generation);
+                }
+
                 foreach (ClrObject obj in objs)
                 {
                     cancellation.ThrowIfCancellationRequested();
index 2c223a6bf01e4834bf3434a5f9e3f1a3c5b88e05..bcb855c79efa467f8a3d80f3ed0adf5dbeb0cc02 100644 (file)
@@ -52,6 +52,11 @@ VERIFY:\s*Statistics:\s+
 VERIFY:\s+MT\s+Count\s+TotalSize\s+Class\s+Name\s+
 VERIFY:\s+<HEXVAL>\s+<DECVAL>\s+<DECVAL>\s+System.Byte\[\]\s+
 
+SOSCOMMAND:DumpHeap -stat -gen poh
+VERIFY:\s*Statistics:\s+
+VERIFY:\s+MT\s+Count\s+TotalSize\s+Class\s+Name\s+
+VERIFY:\s+<HEXVAL>\s+<DECVAL>\s+<DECVAL>\s+System.Byte\[\]\s+
+
 SOSCOMMAND:EEHeap
 VERIFY:\s*Loader Heap:\s+
 VERIFY:\s+System Domain:\s+<HEXVAL>\s+
index 38be904a97016251cd14ee538f05d2862861d477..671e4e2e154b999e36bfad6f31b2d7d6df7594e9 100644 (file)
@@ -82,6 +82,16 @@ VERIFY:\s*Statistics:\s+
 VERIFY:\s+MT\s+Count\s+TotalSize\s+Class\s+Name\s+
 VERIFY:\s+<HEXVAL>\s+<DECVAL>\s+<DECVAL>\s+GCWhere\s+
 
+SOSCOMMAND:DumpHeap -stat -gen gen0
+VERIFY:\s*Statistics:\s+
+VERIFY:\s+MT\s+Count\s+TotalSize\s+Class\s+Name\s+
+VERIFY:\s+<HEXVAL>\s+<DECVAL>\s+<DECVAL>\s+GCWhere\s+
+
+IFDEF:WINDOWS
+SOSCOMMAND:DumpHeap -stat -gen xxx
+VERIFY:\s*System\.ArgumentException: Unknown generation: xxx\. Only gen0, gen1, gen2, loh \(large\), poh \(pinned\) and foh \(frozen\) are supported\s+
+ENDIF:WINDOWS
+
 IFDEF:WINDOWS
 SOSCOMMAND:DumpHeap -strings
 VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+<DECVAL>\s+