dotnet / diagnostics

This repository contains the source code for various .NET Core runtime diagnostic tools and documents.
MIT License
1.18k stars 355 forks source link

Improve dumpgen command or merge it with dumpheap #3963

Closed En3Tho closed 1 year ago

En3Tho commented 1 year ago

Dumpgen is a useful command but it lacks certain features that dumpheap has:

  1. It doesn't show the total combined size of objects in the gen
  2. It doesn't support -live/-dead switches and others

I'm interested in making it better but at the same time looking at those commands, I'm not sure why there are 2 commands that a very similar, e.g. dumpheap and dumpgen Wouldn't it be better to add a gen flag to dumpheap and just leave dumpgen be? Are there some technical difficulties that prevent filtering by both heap and generation? Or live/dead/other switches?

mikem8361 commented 1 year ago

The reason for both commands is historical. dumpheap was written many years ago when SOS was first developed. dumpgen was contributed by 3rd party that needed the filtering (generation). Recently the C++ dumpheap was ported to the C# SOS infrastructure but Lee didn't have enough time to combine the commands. When he comes back from leave he may have time to add an generation option to dumpheap. It looks like dumpheap already has type and method table address filtering.

En3Tho commented 1 year ago

@mikem8361 Thank you for the response. I think I will take a look at it too. Would it be too hard to implement for a contributor w/o much sos knowledge?

leculver commented 1 year ago

It would be very easy. Add a .Where filter to the dumpheap command:

https://github.com/dotnet/diagnostics/blob/main/src/Microsoft.Diagnostics.ExtensionCommands/DumpHeapCommand.cs#L83

Which calls ClrSegment.GetGeneration to match it:

https://github.com/microsoft/clrmd/blob/main/src/Microsoft.Diagnostics.Runtime/ClrSegment.cs#L159-L177

Something like this for dumpheap:

        [Option(Name = "-gen")]
        public string Generation { get; set; }

if (Generation is not null)
{
    Generation target = //..parse Generation
    objectsToPrint = objectsToPrint.Where(o => Runtime.Heap.GetSegmentByAddress(o)?.GetGeneration(o) == target ?? false);
}

Or something similar.

(I won't be back for several months. I won't be implementing this. I only check email and pings once per week while on leave.)

En3Tho commented 1 year ago

@leculver Thanks.

En3Tho commented 1 year ago

@mikem8361 There are both Generation (from Microsoft.Diagnostics.Runtime) and GCGeneration (From extension commands). All the parsing and segment processing logic from DumpGen is implemented in C# already and I wonder if I should remove GCGeneration and instead use Generation everywhere? This might touch different types like DumpGen command, ClrMdHelper etc.