!DumpHeap - possible to disable GC warning?

2019-06-07 14:57发布

问题:

I have a full process dump from an NT service (implemented using C# / .NET 4.5.2) that's in the middle of a GC cycle. When I load it into WinDbg and try to run !DumpHeap -stat (or any other variant of DumpHeap), I get this warning:

The garbage collector data structures are not in a valid state for traversal. It is either in the "plan phase," where objects are being moved around, or we are at the initialization or shutdown of the gc heap. Commands related to displaying, finding or traversing objects as well as gc heap segments may not work properly. !dumpheap and !verifyheap may incorrectly complain of heap consistency errors.

Unfortunately, I cannot (easily) get a clean memory dump outside of GC (I obviously don't know when it happens and I need a dump of some manageable size - the process I'm looking at leaks memory and reaches 18 GB sometimes; this is so big that most heap lookups take over 40 minutes in WinDbg.)

This warning message shows up even when I use the -short parameter to only generate object addresses (to input them into a WinDbg macro) - unfortunately the words of the warning message are passed as input parameters to the macro and the macros blows up. (The macro is a variant of this question and I'm trying to run !GCRoot on a large number of object instances.)

Is there a way to disable this warning message in WinDbg? (DumpHeap is part of SOS, so I guess it needs to be disabled there, if possible.)

Edit: to make it clear, I get useful output from DumpHeap and other commands (which seem mostly consistent), it's just that all output begins with the above warning, even when using -short. This means that I cannot fed the output into other commands.

回答1:

Your question

I understand it is a pity that the -short output contains that message. IMHO the message cannot be disabled.

You can use pykd (Codeplex) to filter the text. You'd need the dbgCommand() function to issue the !dumpheap command. You'll get back a string with the output of the command and you can then filter the text. Next you could push the text back to the debugger with dprint().

Other ideas

  1. Perhaps you want to try taking a dump when .NET is not in the middle of a garbage collection.

  2. Speed up things:

    • sosex has a !bhi command to build a heap index.
    • netext has a !windex command to build a heap index. It even has a command similar to !dumpheap which can be used in the .foreach fashion (from the website):

      .foreach({$addr} {!windex -short -type *.HttpRequest}){!wselect _url.m_String from {$addr} }
      
  3. PyKd: While you're at it, you might also rewrite the .foreach loop in Python and do the !do part in Python as well, allowing you to filter objects based on their content etc. so you might get some time back by using a more intuitive scripting language.