One of these days Microsoft will release a version of .NET where we don’t have to worry about memory. HA! Who am I kidding!? All you worry about in a .NET application is the memory. Naturally, I personally never want Microsoft to come out with the memory worry free .NET because I’d be out of a job.
With SOS for .NET 4.5, there’s not a whole lot different but there are two differences that will be valuable. The first are two new options to the most important SOS command, !dumpheap. One of the big problems in dealing with those minidumps from production systems is trying to figure out which objects are rooted, meaning have references and cannot be garbage collected, and those objects that are ready for garbage collection. That problem is easy to solve with the new –live and –dead options. Get in the habit now of always passing –live when you first do that initial !dumpheap –stat because that’s all you care about!
Here’s an example output comparing the differences reported by –stat alone, -live, and –dead.
What I haven’t been able to figure out is that the total objects between live and dead objects never add up to the total shown when looking at all objects with just the –stat switch. Doing some experimentation the output for –live looks valid so I’m going to trust it for now. I’ll talk to the CLR team and see if this is a bug or there’s a real reason for the discrepancy. It’s not like an object could be alive and dead at the same time… unless it was a ZOMBIE! No matter, the –live switch looks fantastic and will save everyone a huge amount of time.
Since everyone is not moving over to .NET 4.5 immediately, I tried like crazy to see if I could get the .NET 4.5 SOS version working with minidumps from .NET 4.0. Nothing I tried and no amount of playing around with .cordll to load the MSCORDACWKS.DLL from .NET 4.0 would work. Do yourself a favor now and make sure you save off SOS.DLL, CLR.DLL, and MSCORDACWKS.DLL from a pure .NET 4.0 installation because .NET 4.5 is on top of .NET 4.0. I’ll keep working on trying more tricks to get !dumpheap –live working with .NET 4.0.
The second SOS command to get some development love is !clrstack. There’s a new experimental option –i, which uses the CLR Debugging API’s ICorDebug interface to walk stacks and show variable names very much like the !mk command in SOSEX. It’s very important that to use !clrstack –i you have the _NT_SYMBOL_PATH environment variable set to include the public Microsoft symbol server. SOS needs access to MSCORDBI.DLL through the symbol server download even though that DLL is in the framework directory along with SOS.DLL.
Running !clrstack –a –i will show output like the following snippet. What you can’t see is that the output is that it’s fully DML ready.
You are probably wondering where the actual values are. Just like !mk, when it’s JIT optimized code we can’t get the values. That doesn’t make !clrstack –i any less valuable because at least it shows you the types so you can use !dso, or !mdso from SOSEX, to look them up. To turn off the JIT optimizations, you’d have to either run the whole application with the COMPLUS_ZAPDISABLE environment variable or turn it off for an individual assembly with the INI file trick.
The new –live and –dead options for !dumpheap and the –i for !clrstack are the most important additions, but there are a few more worth mentioning. The !bpmd command now supports setting breakpoints on a source and line if you have the PDB file for the assembly loaded. If you’re doing heavy interop, the new !dumprcw, which dumps a Runtime Callable Wrapper, and !dumpccw, which dumps a COM Callable Wrapper, look helpful. The new SOS for .NET 4.5 is nice, but wait until you see the new version of SOSEX!