How to get equivalent info as via !dumpvc with ClrMD RRS feed

  • Question

  • I have just begun using the ClrMD library and have been very happy with it for the most part.   But I'm having problems trying to get the equivalent functionality of accessing an object based on the Method Table as for the WinDbg !dumpvc command.    Not being able to do this has caused me problems with types like System.Data.SqlTypes.SqlDecimal objects.

    SqlDecimal types appear in dumps of DataColumns associated with DataRows as slightly invalid System.Decimal objects - NOT SqlDecimal types.  The "Decimal" equivalents have flag word bit sequences with non-zero bit content in places in the Flags word that are guaranteed in the MSDN references to always be zero.  I've been getting by with trying to manually reconstruct the values by directly reading the underlying memory.  But while the bits layout is well-documented for System.Decimal, I could not find the equivalent full bits layout showing which bits are where, layout detailing the extra bit fields used for Precision, different Scale, etc.   Not having the exact bit layout makes explicit bit-shifting a bit of a guessing game. 

    I've tried getting the underlying SqlDecimal ClrType from the heap and using its Fields information to get values, but cannot seem to get this to work.   Yet I can go into WinDbg, get the MethodTable address for SqlDecimal, and !dumpvc <MT-of-SqlDecimal> <ObjAddress> with no problem.   I'm hoping there is something equivalent in ClrMD that I just haven't yet found.

    Can anyone shed any light on the best way to reconstruct value class values with ClrMD?  Is doing it via getting a ClrType for the underlying GC type; then getting data via "Fields" preferable and I'm just doing it wrong?   Or is one-at-a-time, manually reconstructing an equivalent object in code based on data obtained thru raw memory reads really the only way to make this work?

    Thanks in advance,

    • Edited by Bob Riddle Tuesday, January 21, 2014 9:30 PM
    Tuesday, January 21, 2014 9:23 PM


  • Hi All,

    I ran across this information in a StackOverflow posting at http://stackoverflow.com/questions/22150259/how-to-properly-work-with-non-primitive-clrinstancefield-values-using-clrmd by user "Tomasr".    It seems to address my question; at least when the class references you're trying to resolve to values are from elements of arrays - which is what I was doing when I first hit the problem and started this thread.  So I'm going to mark my question here as answered by this reply.  In part, that link reads:


    The first thing you need to know in order to be able to call GetFieldAddress/GetFieldValue is if the object address you have is a regular pointer or an interior pointer. That is, if it directly points to an object on the heap, or to an interior structure within an actual object (think String vs. Struct field within an actual object).

    If you're getting the wrong values out of GetFieldAddress/GetFieldValue, it usually means you're not specifying
    that you have an interior pointer (or you thought you had one when you didn't).

    The second part is understanding what the values mean.

    If field.IsPrimitive() is true: GetFieldValue() will get you the actual primitive value (i.e. an Int32, Byte, or whatever)

    If field.IsValueClass() is true, then GetFieldAddress() will get you an interior pointer to the structure. Thus, any calls on GetFieldAddress/Value() that you use on that address you need to tell it  that it is an interior pointer!

    If field.ElementType is a ClrElementType.String, then I seem to remember you need to call GetFieldValue will get you the actual string contents (need to check, but this should be it).

    Otherwise, you have an object reference, in which case GetFieldValue() will get you a regular pointer to the new reference object.


    A tip of my hat to "Tomasr" and please refer to that StackOverflow link for context and any additional postings on that thread.

    Thanks to all,


    • Edited by Bob Riddle Thursday, March 6, 2014 9:33 PM
    • Marked as answer by Bob Riddle Thursday, March 6, 2014 9:39 PM
    Thursday, March 6, 2014 9:33 PM