Saturday, 07 March 2009
« Hall of Shame - | Main | SOSEX v4.0 Now Available »

At long last, I’m pleased to announce the availability of SOSEX version 2.0.  This is a major overhaul of the extension that optimizes and enhances existing functionality, adds many new features, and changes the command naming scheme to be more like the built-in debugger engine commands.  I’ve added support for many of the staple debugger commands by implementing similar functionality and prefixing the commands with “m” (managed).  Included are: mbp, mbm, mbl, mbc, mbe, mbd, mdt, mdv, mframe, mk, mln and mx.

Here’s a quick overview of new things you can do with SOSEX v2:

  • Search the heaps for FREE objects by using the new “-free” switch to the “dumpgen” command.  This helps in diagnosing managed heap fragmentation
  • Search the heaps for string objects using the new “strings” command.  You can search for strings matching criteria including min length, max length, gen # and string filter
  • Specify one-shot, pass count and command for all your managed breakpoints using new breakpoint options
  • Set breakpoints on methods that match a wildcard search pattern
  • See your full callstack, managed and unmanaged frames, with the “mk” command.  This isn’t straightforward to do with the “clrstack” and “k” commands
  • Find type, method and field names in managed assemblies using the “mx” command
  • Find out what type of managed data, if any, is located at a given address with the “mln”

Be sure to check out “help” or “sosexhelp” for all commands to ensure you’re aware of all the new goodies.  Stay tuned in the coming days and weeks, as I’ll be posting articles that dive into each individual command in detail.  To start with, though, I’d like to provide an overview of my personal favorite new feature: the “mdt” (Managed Display Type) command.

!mdt allows you to dump the fields of a given type by type name or to examine the fields of an object or value type instance.  Not only can you examine the fields of an object or value type instance, but you can also examine an entire object graph by specifying the “-r” (recursive) switch.  Want to examine a local variable or argument?  No problem.  Just enter “!mdt <Var Name>”, and voila!  The best way to demonstrate the power of this command is with a few examples.

0:000> !mdt System.DateTime 003bef0c
003bef0c (System.DateTime) 2008/01/02 03:04:05.678 VALTYPE (MT=65cd9e98, ADDR=003bef0c)

0:000> !mdt theGuid
003bef1c (System.Guid) {29b9c9c8-3751-42be-8c7a-8b92ff499588} VALTYPE (MT=65cd6c60, ADDR=003bef1c)

0:000> !mdt ConsoleTestApp.TestStruct
   Member1: uint
   Member2: uint

0:000> !mdt ConsoleTestApp.TestStruct 003bef04
003bef04 (ConsoleTestApp.TestStruct) VALTYPE (MT=001b3198, ADDR=003bef04)
   Member1:0x162E (System.UInt32)
   Member2:0x451434E0 (System.UInt32)

0:000> !mdt 6487ce0
06487ce0 (System.Runtime.Remoting.Proxies.__TransparentProxy)
   _rp:06487cb4 (System.Runtime.Remoting.Proxies.RemotingProxy)
   _stubData:06482a5c (BOXED System.IntPtr) VALTYPE (MT=65cfb114, ADDR=06482a60)
   _pMT:65cf902c (System.IntPtr)
   _pInterfaceMT:00000000 (System.IntPtr)
   _stub:68c71e70 (System.IntPtr)

0:000> !mdt 6487ce0 -r
06487ce0 (System.Runtime.Remoting.Proxies.__TransparentProxy)
   _rp:06487cb4 (System.Runtime.Remoting.Proxies.RemotingProxy)
      _tp:06487ce0 (System.Runtime.Remoting.Proxies.__TransparentProxy)
      _identity:06487a98 (System.Runtime.Remoting.Identity)
         _flags:0x4 (System.Int32)
         _tpOrObject:06487ce0 (System.Runtime.Remoting.Proxies.__TransparentProxy)
         _ObjURI:06484c88 (System.String: "/49cf1154_ea17_4f51_b666_8f91a1263a00/0um3p4he0mnsfugppw1z7gkd_1.rem")
         _URL:NULL (System.String)
         _objRef:06484e10 (System.Runtime.Remoting.ObjRef)
            uri:06484c88 (System.String: "/49cf1154_ea17_4f51_b666_8f91a1263a00/0um3p4he0mnsfugppw1z7gkd_1.rem")
            typeInfo:064850f4 (System.Runtime.Remoting.TypeInfo)
               serverType:064862d4 (System.String: "System.AppDomain, mscorlib, Version=, Culture=neutral…
               serverHierarchy:NULL (System.Object[])
               interfacesImplemented:064864bc (System.String[], Elements: 2)
            envoyInfo:NULL (System.Runtime.Remoting.IEnvoyInfo)
            channelInfo:06486b5c (System.Runtime.Remoting.ChannelInfo)
               channelData:06486b68 (System.Object[], Elements: 1)
            objrefFlags:0x0 (System.Int32)
            srvIdentity:06484e2c (System.Runtime.InteropServices.GCHandle) VALTYPE (MT=65cfbcb8, ADDR=06484e2c)
               m_handle:007e11ec (System.IntPtr)
            domainID:0x2 (System.Int32)
         _channelSink:06487c90 (System.Runtime.Remoting.Channels.CrossAppDomainSink)
            _xadData:06483834 (System.Runtime.Remoting.Channels.CrossAppDomainData)
               _ContextID:06483854 (BOXED System.Int32) BOXEDVAL=0x87C330
               _DomainID:0x2 (System.Int32)
               _processGuid:06483530 (System.String: "88866410_d263_4d8a_b901_8278132285be")
         _envoyChain:06487ca8 (System.Runtime.Remoting.Messaging.EnvoyTerminatorSink)
         _dph:NULL (System.Runtime.Remoting.Contexts.DynamicPropertyHolder)
         _lease:NULL (System.Runtime.Remoting.Lifetime.Lease)
      _serverObject:NULL (System.MarshalByRefObject)
      _flags:0x3 (System.Runtime.Remoting.Proxies.RealProxyFlags)
      _srvIdentity:06487cd0 (System.Runtime.InteropServices.GCHandle) VALTYPE (MT=65cfbcb8, ADDR=06487cd0)
         m_handle:007e11ec (System.IntPtr)
      _optFlags:0x7000000 (System.Int32)
      _domainID:0x2 (System.Int32)
      _ccm:NULL (System.Runtime.Remoting.Messaging.ConstructorCallMessage)
      _ctorThread:0x0 (System.Int32)
   _stubData:06482a5c (BOXED System.IntPtr) VALTYPE (MT=65cfb114, ADDR=06482a60)
      m_value:ffffffff (System.UIntPtr)
   _pMT:65cf902c (System.IntPtr)
   _pInterfaceMT:00000000 (System.IntPtr)
   _stub:68c71e70 (System.IntPtr)

I hope you enjoy using SOSEX v2.0 as much as I’ve enjoyed writing it!

Download: 32-bit  64-bit