Update DumpObj command to show TrackedType and TaggedMemory (#2407)
authorAaron Robinson <arobins@microsoft.com>
Fri, 2 Jul 2021 20:49:43 +0000 (13:49 -0700)
committerGitHub <noreply@github.com>
Fri, 2 Jul 2021 20:49:43 +0000 (13:49 -0700)
* Update DumpObj command to show TrackedType and TaggedMemory if applicable.

* Update DML for tagged memory to compute the pointer size of memory dynamically.

src/SOS/Strike/strike.cpp
src/SOS/Strike/util.cpp
src/SOS/Strike/util.h
src/inc/sospriv.idl
src/pal/prebuilt/idl/sospriv_i.cpp
src/pal/prebuilt/inc/sospriv.h

index 65f3a980a09fc3289b36a61c2136570fdc63304f..3d74a7aadf6f43dbfb4abec3dcf1608635d8d08f 100644 (file)
@@ -1570,6 +1570,27 @@ HRESULT PrintObj(TADDR taObj, BOOL bPrintFields = TRUE)
         }
     }
 
+    // Check for Tracked Type and tagged memory
+    ReleaseHolder<ISOSDacInterface11> sos11;
+    if (SUCCEEDED(g_sos->QueryInterface(__uuidof(ISOSDacInterface11), &sos11)))
+    {
+        CLRDATA_ADDRESS objAddr = TO_CDADDR(taObj);
+        BOOL isTrackedType;
+        BOOL hasTaggedMemory;
+        if (SUCCEEDED(sos11->IsTrackedType(objAddr, &isTrackedType, &hasTaggedMemory)))
+        {
+            ExtOut("Tracked Type: %s\n", isTrackedType ? "true" : "false");
+            if (hasTaggedMemory)
+            {
+                CLRDATA_ADDRESS taggedMemory = NULL;
+                size_t taggedMemorySizeInBytes = 0;
+                (void)sos11->GetTaggedMemory(objAddr, &taggedMemory, &taggedMemorySizeInBytes);
+                DMLOut("Tagged Memory: %s (%" POINTERSIZE_TYPE "d(0x%" POINTERSIZE_TYPE "x) bytes)\n",
+                    DMLTaggedMemory(taggedMemory, taggedMemorySizeInBytes / sizeof(void*)), taggedMemorySizeInBytes, taggedMemorySizeInBytes);
+            }
+        }
+    }
+
     DWORD_PTR size = (DWORD_PTR)objData.Size;
     ExtOut("Size:        %" POINTERSIZE_TYPE "d(0x%" POINTERSIZE_TYPE "x) bytes\n", size, size);
 
index e96899872f4410ecc8f7a4a96990b658329fe5d9..6123b3b02be865ed45d36b59ea9f5e8072809d80 100644 (file)
@@ -4741,6 +4741,7 @@ const char * const DMLFormats[] =
     "<exec cmd=\"!DumpIL /i %s\">%s</exec>",         // DML_IL
     "<exec cmd=\"!DumpRCW -cw /d %s\">%s</exec>",    // DML_ComWrapperRCW
     "<exec cmd=\"!DumpCCW -cw /d %s\">%s</exec>",    // DML_ComWrapperCCW
+    "<exec cmd=\"dps %s L%d\">%s</exec>",            // DML_TaggedMemory
 };
 
 void ConvertToLower(__out_ecount(len) char *buffer, size_t len)
@@ -4783,6 +4784,29 @@ CachedString Output::BuildHexValue(CLRDATA_ADDRESS addr, FormatType type, bool f
     return ret;
 }
 
+CachedString Output::BuildHexValueWithLength(CLRDATA_ADDRESS addr, size_t len, FormatType type, bool fill)
+{
+    CachedString ret;
+    if (ret.IsOOM())
+    {
+        ReportOOM();
+        return ret;
+    }
+
+    if (IsDMLEnabled())
+    {
+        char hex[POINTERSIZE_BYTES*2 + 1];
+        GetHex(addr, hex, _countof(hex), fill);
+        sprintf_s(ret, ret.GetStrLen(), DMLFormats[type], hex, len, hex);
+    }
+    else
+    {
+        GetHex(addr, ret, ret.GetStrLen(), fill);
+    }
+
+    return ret;
+}
+
 CachedString Output::BuildVCValue(CLRDATA_ADDRESS mt, CLRDATA_ADDRESS addr, FormatType type, bool fill)
 {
     _ASSERTE(type == DML_ValueClass);
index a84aec209a5538f0f6f3e845d992a6d7ccb940d1..51c3da0c648792077a53378a5f9fe0281ed32c09 100644 (file)
@@ -564,7 +564,8 @@ namespace Output
         DML_Async,
         DML_IL,
         DML_ComWrapperRCW,
-        DML_ComWrapperCCW
+        DML_ComWrapperCCW,
+        DML_TaggedMemory
     };
 
     /**********************************************************************\
@@ -597,6 +598,21 @@ namespace Output
     \**********************************************************************/
     CachedString BuildHexValue(CLRDATA_ADDRESS addr, FormatType type, bool fill = true);
 
+    /**********************************************************************\
+    * This function builds a DML string for an object.  If DML is enabled, *
+    * this function returns a DML string based on the format type.         *
+    * Otherwise this returns a string containing only the hex value of     *
+    * addr.                                                                *
+    *                                                                      *
+    * Params:                                                              *
+    *   addr - the address of the object                                   *
+    *   len  - associated length                                           *
+    *   type - the format type to use to output this object                *
+    *   fill - whether or not to pad the hex value with zeros              *
+    *                                                                      *
+    \**********************************************************************/
+    CachedString BuildHexValueWithLength(CLRDATA_ADDRESS addr, size_t len, FormatType type, bool fill = true);
+
     /**********************************************************************\
     * This function builds a DML string for an managed variable name.      *
     * If DML is enabled, this function returns a DML string that will      *
@@ -672,6 +688,7 @@ inline void ExtOutIndent()  { WhitespaceOut(Output::g_Indent << 2); }
 #define DMLIL(addr) Output::BuildHexValue(addr, Output::DML_IL).GetPtr()
 #define DMLComWrapperRCW(addr) Output::BuildHexValue(addr, Output::DML_ComWrapperRCW).GetPtr()
 #define DMLComWrapperCCW(addr) Output::BuildHexValue(addr, Output::DML_ComWrapperCCW).GetPtr()
+#define DMLTaggedMemory(addr, len) Output::BuildHexValueWithLength(addr, len, Output::DML_TaggedMemory).GetPtr()
 
 bool IsDMLEnabled();
 
index 332ec79c50aa9748542d0814e3dec8e050a633ce..102801f7e5d3e78b75f121a6f780fde176e15d03 100644 (file)
@@ -438,3 +438,14 @@ interface ISOSDacInterface10 : IUnknown
     HRESULT IsComWrappersRCW(CLRDATA_ADDRESS rcw, BOOL *isComWrappersRCW);
     HRESULT GetComWrappersRCWData(CLRDATA_ADDRESS rcw, CLRDATA_ADDRESS *identity);
 }
+
+[
+    object,
+    local,
+    uuid(96BA1DB9-14CD-4492-8065-1CAAECF6E5CF)
+]
+interface ISOSDacInterface11 : IUnknown
+{
+    HRESULT IsTrackedType(CLRDATA_ADDRESS objAddr, BOOL* isTrackedType, BOOL* hasTaggedMemory);
+    HRESULT GetTaggedMemory(CLRDATA_ADDRESS objAddr, CLRDATA_ADDRESS* taggedMemory, size_t* taggedMemorySizeInBytes);
+}
index 214e5bee2cbb83b7b277915746ca10c88a3ce8d4..8f0be3732ff96c2db3789197bd585a3597bd8c0a 100644 (file)
@@ -109,6 +109,9 @@ MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface9,0x4eca42d8,0x7e7b,0x4c8a,0xa1,0x16,0
 MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface10,0x90B8FCC3,0x7251,0x4B0A,0xAE,0x3D,0x5C,0x13,0xA6,0x7E,0xC9,0xAA);
 
 
+MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface11,0x96BA1DB9,0x14CD,0x4492,0x80,0x65,0x1C,0xAA,0xEC,0xF6,0xE5,0xCF);
+
+
 #undef MIDL_DEFINE_GUID
 
 #ifdef __cplusplus
index 1cfc2a1f34487c82a49f73d9daee10e1dc6c99be..de72fa2c95881004266bcff37ad6b4da52a366ec 100644 (file)
@@ -2898,6 +2898,103 @@ EXTERN_C const IID IID_ISOSDacInterface10;
 
 #endif  /* __ISOSDacInterface10_INTERFACE_DEFINED__ */
 
+#ifndef __ISOSDacInterface11_INTERFACE_DEFINED__
+#define __ISOSDacInterface11_INTERFACE_DEFINED__
+
+/* interface ISOSDacInterface11 */
+/* [uuid][local][object] */ 
+
+
+EXTERN_C const IID IID_ISOSDacInterface11;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+    
+    MIDL_INTERFACE("96BA1DB9-14CD-4492-8065-1CAAECF6E5CF")
+    ISOSDacInterface11 : public IUnknown
+    {
+    public:
+        virtual HRESULT STDMETHODCALLTYPE IsTrackedType( 
+            CLRDATA_ADDRESS objAddr,
+            BOOL *isTrackedType,
+            BOOL *hasTaggedMemory) = 0;
+        
+        virtual HRESULT STDMETHODCALLTYPE GetTaggedMemory( 
+            CLRDATA_ADDRESS objAddr,
+            CLRDATA_ADDRESS *taggedMemory,
+            size_t *taggedMemorySizeInBytes) = 0;
+        
+    };
+    
+    
+#else  /* C style interface */
+
+    typedef struct ISOSDacInterface11Vtbl
+    {
+        BEGIN_INTERFACE
+        
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( 
+            ISOSDacInterface11 * This,
+            /* [in] */ REFIID riid,
+            /* [annotation][iid_is][out] */ 
+            _COM_Outptr_  void **ppvObject);
+        
+        ULONG ( STDMETHODCALLTYPE *AddRef )( 
+            ISOSDacInterface11 * This);
+        
+        ULONG ( STDMETHODCALLTYPE *Release )( 
+            ISOSDacInterface11 * This);
+        
+        HRESULT ( STDMETHODCALLTYPE *IsTrackedType )( 
+            ISOSDacInterface11 * This,
+            CLRDATA_ADDRESS objAddr,
+            BOOL *isTrackedType,
+            BOOL *hasTaggedMemory);
+        
+        HRESULT ( STDMETHODCALLTYPE *GetTaggedMemory )( 
+            ISOSDacInterface11 * This,
+            CLRDATA_ADDRESS objAddr,
+            CLRDATA_ADDRESS *taggedMemory,
+            size_t *taggedMemorySizeInBytes);
+        
+        END_INTERFACE
+    } ISOSDacInterface11Vtbl;
+
+    interface ISOSDacInterface11
+    {
+        CONST_VTBL struct ISOSDacInterface11Vtbl *lpVtbl;
+    };
+
+    
+
+#ifdef COBJMACROS
+
+
+#define ISOSDacInterface11_QueryInterface(This,riid,ppvObject) \
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 
+
+#define ISOSDacInterface11_AddRef(This) \
+    ( (This)->lpVtbl -> AddRef(This) ) 
+
+#define ISOSDacInterface11_Release(This) \
+    ( (This)->lpVtbl -> Release(This) ) 
+
+
+#define ISOSDacInterface11_IsTrackedType(This,objAddr,isTrackedType,hasTaggedMemory) \
+    ( (This)->lpVtbl -> IsTrackedType(This,objAddr,isTrackedType,hasTaggedMemory) ) 
+
+#define ISOSDacInterface11_GetTaggedMemory(This,objAddr,taggedMemory,taggedMemorySizeInBytes) \
+    ( (This)->lpVtbl -> GetTaggedMemory(This,objAddr,taggedMemory,taggedMemorySizeInBytes) ) 
+
+#endif /* COBJMACROS */
+
+
+#endif  /* C style interface */
+
+
+
+
+#endif  /* __ISOSDacInterface11_INTERFACE_DEFINED__ */
+
 
 /* Additional Prototypes for ALL interfaces */