dotnet / diagnostics

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

Pinpointing a static gcroot with sos #1922

Open eventhorizon-cli opened 3 years ago

eventhorizon-cli commented 3 years ago

How can I determine which static field of which class is responsible for the static reference when using gcroot command. The result of gcroot only shows the types. image

tommcdon commented 3 years ago

@mikem8361

mikem8361 commented 3 years ago

I'm not sure is gcroot can tell you the name of the static roots. @Maoni0, @cshung, @dotnet/dotnet-diag any ideas?

hoyosjs commented 3 years ago

I can't think of anything short of adding a full pass of symbol support on SOS.

Maoni0 commented 3 years ago

if I see this pattern - pinned handle -> object[] -> object

I will just assume that those are very likely static objects because static objects are always in an object[] pointed to by a pinned handle :smile:

noahfalk commented 3 years ago

With SOS today I am not aware of any option better than educated guessing/detective work. What @Maoni0 wrote is a very good heuristic for "Is this a static field reference?" If you further want to know what type and field the reference is through you can often get good clues by examining the type or examining the content of the object and then correlating what you see back to the source code.

With more development work on SOS this story could be improved. SOS could enumerate every loaded type, then enumerate every static field to determine which, if any, matched a given object of interest. I don't recall offhand but it is possible that Visual Studio's memory snapshot analysis already does that. If no tool has the feature right now you could probably write a write a tiny console app using CLRMD to automate that search for you.

eventhorizon-cli commented 3 years ago

image Thanks, Visual Studio can show the path. @noahfalk

davidfowl commented 3 years ago

@EventHorizon1024 don't use concurrent bag, it's a trap 😄

leculver commented 7 months ago

I ran into this today. It would have been really nice to have had this feature in SOS for something I'm investigating in AzureWatson. (Yep, it was ConcurrencyBag.)

I'm assigning this to myself, it should be fixable, but we'll probably have to put it behind a flag like -resolveStatics since this will be very slow in large dump files. We have to enumerate every static/threadstatic field (the APIs don't support lookup by address) and that takes a ton of time in processes with a lot of types and modules.