Evgeny0

Hi,

I'm writing a tool that analyses a managed memory dump. It uses dbgeng to read the dump and also uses SOS for some things. I'd like to get a list of all the GC handles and there seems to be no way to do this with SOS. The GCHandleLeaks command is close, but it only lists the strong and pinned handles and is only available in CLR 2.0 (I'd like my tool to work with 1.1 as well). Is there any documentation, however unofficial, that would help me to find the handle tables in the memory dump and read them to get the handles I know that this is all internal stuff, "undocumented and subject to change", but maybe there's something along the lines of the excellent "JIT and Run" MSDN Magazine article.

Thanks in advance for any help!

Evgeny


Re: Building Development and Diagnostic Tools for .Net Finding and reading handle tables

Diane Law

Evgeny,

We don't currently have a way to do this. Up to now, I guess no one has really felt a need for this capability, so I'm curious to know exactly what you were wanting to do this for

BTW, you can get an updated version of the debugger tools for 1.1 from http://www.microsoft.com/whdc/devtools/debugging/default.mspx and I believe it may have the GCHandleLeaks command.

Thanks,

Diane





Re: Building Development and Diagnostic Tools for .Net Finding and reading handle tables

Evgeny0

Hi Diane,

Thanks for your reply. I'd like to find out what objects are being kept alive by handles. I haven't found the !GCHandleLeaks command for .NET 1.1, but it's not quite what I want anyway. In addition to what I mentioned in my first post, it searches for references to the handles in memory and that can take a long time with a large dump, whereas just getting the handles should be very fast. I should be able to read the handle table from memory myself. The handles returned by !GCHandleLeaks seem to all be laid out nicely next to each other, so it seems to be just a matter of finding where the handle table for each domain begins and ends. Do you know if this information is available anywhere




Re: Building Development and Diagnostic Tools for .Net Finding and reading handle tables

Jon Langdon - MSFT

Evgeny,

Can you help us understand the big-picture problem you're trying to solve At best there may be other approaches for solving it, and if not we'll have a better idea of how we might address this in the future.

Thanks,
Jon





Re: Building Development and Diagnostic Tools for .Net Finding and reading handle tables

Diane Law - MSFT

Evgeny,

Actually, you've put your finger on the problem exactly. It's a simple enough matter to get the start of each handle table. !GCHandles will give you that. What's not available is where the end of the table is. In fact, it's possible that part of a particular handle table may not even be mapped at a particular point in execution. That more or less precludes being able to do anything like reading consecutive values until you hit something that no longer looks like a handle (i.e., not NULL and the referent lies within the heap segments, which are available via the !eeheap -gc command).

You're right that the time that !GCHandleLeaks takes is mostly due to searching for the references in memory. Thus, the !GCHandles command would be better suited to your purposes, except it doesn't actually print the handles, it just counts them. This is something we've never had any demand for (until now :-)). It would be interesting to know if others would find this useful too.

I'm still curious why you're wanting to know what objects are being kept alive specifically by handles. Is this part of a larger task of finding all live objects The output here could be tremendously large, so it might not be the most useful information to provide.

Diane





Re: Building Development and Diagnostic Tools for .Net Finding and reading handle tables

Evgeny0

Thanks, Diane, but I cannot find the handle table start anywhere in the !GCHandles output. All it gives me is the count of each type of handle. So how does SOS itself actually find the start and end of the handle table Also, even if a part of the handle table is not mapped at a given time, wouldn't it still be possible to just go through to the end address (I presume there is such a thing as the end address Smile), looking for things that look like valid handles

The larger task is finding all root objects. !DumpStackObjects conveniently give me the stack roots and !FinalizeQueue allows me to get the finalizer queue ones. Handle roots are the problem! The even larger task is finding root paths for a given object, ie. what !gcroot does, but making a different space-time tradeoff. I find that !gcroot is great for a small memory dump and the whole analysis doesn't take much memory (at least in .NET 1.1), but it takes a really long time with a large dump.




Re: Building Development and Diagnostic Tools for .Net Finding and reading handle tables

Diane Law - MSFT

Evgeny,

The starting addresses for the handle tables are at the beginning of the output from !GCHandles (I used the debugging tools downloaded from http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx). The output from 2.0 is similar. In this case, we have three tables.


0:000> !GCHandles
Loaded Son of Strike data table version 5 from "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\mscorsvr.dll"
Scan HandleTable 0x148c90
Scan HandleTable 0x14d9e8
Scan HandleTable 0x1c8fb0

Unfortunately, we don't have a way to give you the end of the tables (although they do have an end, as you suppose!). If you try to read an unmapped address, you'll AV, so I wouldn't advise trying to traverse them blindly.


So correct me where I'm misinterpreting you. It sounds like perhaps you're planning to save time getting the information that !GCRoot gives by doing some kind of pre-analysis of the dump file. Is that correct What exactly do you plan to store that will make this more efficient What kind of analysis do you mean to do I'm asking, because I'm having trouble understanding how you'll be able to speed things up.

Thanks,
Diane





Re: Building Development and Diagnostic Tools for .Net Finding and reading handle tables

Evgeny0

Hi Dianne,

I've just tried using the sos.dll in the clr10 directory under Debugging Tools and yes, it does show the output above. I've been trying the sos.dll supplied with .NET Framework 1.1, since "clr10" implied to me that it's only for .NET 1.0. It seems to work with 1.1 as well, but not with 2.0. So with that said, it looks like I can use !GCHandleLeaks to list the strong and pinned handles under both 1.1 and 2.0. I suppose I'd have to try aborting the command once it gets to searching memory and ignoring the rest of the output, which is a bit of a hack. There are still the reference-counted handles, which I don't know how to get, so it's by no means an ideal solution, but it's a start.

I don't really want to make a fool of myself here by trying to describe how I'd implement gcroot Smile without really knowing whether it'll work. I'm not sure that it can be done, but I'd like to give it a shot, that's all. The starting point is finding the roots, so that's where I'm starting!

Evgeny




Re: Building Development and Diagnostic Tools for .Net Finding and reading handle tables

Diane Law - MSFT

Evgeny,

Believe me, I'm not trying to get you to "make a fool of yourself!" :-) If that's enough to get you started, maybe you can do enough initial proof-of-concept work to determine whether you want to pursue this further. If you need more help, please post back to this thread.

Diane