Add SOS DumpALC command
authorJan Vorlicek <janvorli@microsoft.com>
Wed, 24 Jun 2020 23:51:33 +0000 (01:51 +0200)
committerJan Vorlicek <janvorli@microsoft.com>
Wed, 24 Jun 2020 23:51:33 +0000 (01:51 +0200)
This change adds a new SOS command to dump an AssemblyLoadContext for an
object. The dumped ALC is the one into which the object's type is
loaded.

src/SOS/Strike/sos.def
src/SOS/Strike/sos_unixexports.src
src/SOS/Strike/sosdocs.txt
src/SOS/Strike/sosdocsunix.txt
src/SOS/Strike/strike.cpp
src/SOS/lldbplugin/soscommand.cpp
src/Tools/dotnet-dump/Commands/SOSCommand.cs
src/inc/sospriv.idl
src/pal/prebuilt/idl/sospriv_i.cpp
src/pal/prebuilt/inc/sospriv.h

index ec85ef31c3e552ca3d487c39fe5598f00d1e7f47..edf8a8ba1c7361b49520cc0fff65f4ca99178979 100644 (file)
@@ -10,6 +10,8 @@ EXPORTS
     ClrStack
     clrstack=ClrStack
     CLRStack=ClrStack
+    DumpALC
+    dumpalc=DumpALC
     DumpArray
     da=DumpArray
     dumparray=DumpArray
index edfd21f90a9d329cd584234bffa42135ab2425de..e7e516d4e9daca1e768b3596b911fb71f54600b4 100644 (file)
@@ -5,6 +5,7 @@
 bpmd
 ClrStack
 dbgout
+DumpALC
 DumpArray
 DumpAssembly
 DumpAsync
index 8ec0fcc3574446d09781d98352af3b9af52e64d8..f4b95a40631050a7ef16eba98eeee737fc0c6a09 100644 (file)
@@ -24,16 +24,17 @@ Type "!help <functionname>" for detailed info on that function.
 Object Inspection                  Examining code and stacks
 -----------------------------      -----------------------------
 DumpObj (do)                       Threads (clrthreads)
-DumpArray (da)                     ThreadState
-DumpAsync                          IP2MD
-DumpDelegate                       U
-DumpStackObjects (dso)             DumpStack
-DumpHeap                           EEStack
-DumpVC                             ClrStack
-GCRoot                             GCInfo
-ObjSize                            EHInfo
-FinalizeQueue                      BPMD (bpmd)
-PrintException (pe)                COMState
+DumpALC (dumpalc)                  ThreadState
+DumpArray (da)                     IP2MD
+DumpAsync                          U
+DumpDelegate                       DumpStack
+DumpStackObjects (dso)             EEStack
+DumpHeap                           ClrStack
+DumpVC                             GCInfo
+GCRoot                             EHInfo
+ObjSize                            BPMD (bpmd)
+FinalizeQueue                      COMState
+PrintException (pe)
 TraverseHeap
 
 Examining CLR data structures      Diagnostic Utilities
@@ -324,6 +325,42 @@ The arguments in detail:
 
 \\
 
+COMMAND: dumpalc.
+DumpALC
+    <object address>
+
+This command allows you to dump the AssemblyLoadContext into which the type of the
+specified object was loaded.
+
+ Example output:
+        0:000> !dumpalc 000001c2800101a0
+        Name:        Host.HostAssemblyLoadContext
+        MethodTable: 00007ff7c9cb1428
+        EEClass:     00007ff7c9ca4b40
+        Size:        88(0x58) bytes
+        File:        c:\test\host.dll
+        Fields:
+                      MT    Field   Offset                 Type VT     Attr            Value Name
+        00007ff7c9920eb8  4000ea3        8        System.Object  0 instance 000001c28000cff0 _unloadLock
+        0000000000000000  4000ea4       10                       0 instance 0000000000000000 _resolvingUnmanagedDll
+        0000000000000000  4000ea5       18                       0 instance 0000000000000000 _resolving
+        00007ff7c9d36850  4000ea6       20 ...Private.CoreLib]]  0 instance 000001c2800101b8 _unloading
+        00007ff7c9a74748  4000ea7       28        System.String  0 instance 0000000000000000 _name
+        00007ff7c9a427f0  4000ea8       30        System.IntPtr  1 instance 000001C2FA21DD50 _nativeAssemblyLoadContext
+        00007ff7c9a1c7e0  4000ea9       38         System.Int64  1 instance                0 _id
+        00007ff7c9ac57b8  4000eaa       40         System.Int32  1 instance                0 _state
+        00007ff7c9a107b8  4000eab       44       System.Boolean  1 instance                1 _isCollectible
+        00007ff7c9cb4070  4000ea1      b08 ...Private.CoreLib]]  0   static 000001c28000d090 s_allContexts
+        00007ff7c9a1c7e0  4000ea2      970         System.Int64  1   static                1 s_nextId
+        0000000000000000  4000eac      b10 ...yLoadEventHandler  0   static 0000000000000000 AssemblyLoad
+        0000000000000000  4000ead      b18 ...solveEventHandler  0   static 0000000000000000 TypeResolve
+        0000000000000000  4000eae      b20 ...solveEventHandler  0   static 0000000000000000 ResourceResolve
+        0000000000000000  4000eaf      b28 ...solveEventHandler  0   static 0000000000000000 AssemblyResolve
+        0000000000000000  4000eb0      b30                       0   static 0000000000000000 s_asyncLocalCurrent
+        00007ff7c9cb26d0  4000001       48 ...ependencyResolver  0 instance 000001c28000d1c0 _resolver
+
+\\
+
 COMMAND: dumpasync.
 !DumpAsync [-addr <Object Address>]
            [-mt <MethodTable address>]
index 00cebe718bd56e56fd63fbfc688dfb9535e544fb..00ccddb8c0a436aae543fb56ac03eba8835caee2 100644 (file)
@@ -24,15 +24,16 @@ Type "soshelp <functionname>" for detailed info on that function.
 Object Inspection                  Examining code and stacks
 -----------------------------      -----------------------------
 DumpObj (dumpobj)                  Threads (clrthreads)
-DumpArray                          ThreadState
-DumpAsync (dumpasync)              IP2MD (ip2md)
-DumpDelegate (dumpdelegate)        u (clru)
-DumpStackObjects (dso)             DumpStack (dumpstack)
-DumpHeap (dumpheap)                EEStack (eestack)
-DumpVC                             ClrStack (clrstack)
-FinalizeQueue (finalizequeue)      GCInfo
-GCRoot (gcroot)                    EHInfo
-PrintException (pe)                bpmd (bpmd)
+DumpALC (dumpalc)                  ThreadState
+DumpArray                          IP2MD (ip2md)
+DumpAsync (dumpasync)              u (clru)
+DumpDelegate (dumpdelegate)        DumpStack (dumpstack)
+DumpStackObjects (dso)             EEStack (eestack)
+DumpHeap (dumpheap)                ClrStack (clrstack)
+DumpVC                             GCInfo
+FinalizeQueue (finalizequeue)      EHInfo
+GCRoot (gcroot)                    bpmd (bpmd)
+PrintException (pe)
                                    
 Examining CLR data structures      Diagnostic Utilities
 -----------------------------      -----------------------------
@@ -192,6 +193,42 @@ The arguments in detail:
         5b9a628c  4000003        8         System.Int32   instance       12 z
 \\
 
+COMMAND: dumpalc.
+DumpALC
+    <object address>
+
+This command allows you to dump the AssemblyLoadContext into which the type of the
+specified object was loaded.
+
+ Example output:
+        (lldb) dumpalc 000001c2800101a0
+        Name:        Host.HostAssemblyLoadContext
+        MethodTable: 00007ff7c9cb1428
+        EEClass:     00007ff7c9ca4b40
+        Size:        88(0x58) bytes
+        File:        /home/user/test/host.dll
+        Fields:
+                      MT    Field   Offset                 Type VT     Attr            Value Name
+        00007ff7c9920eb8  4000ea3        8        System.Object  0 instance 000001c28000cff0 _unloadLock
+        0000000000000000  4000ea4       10                       0 instance 0000000000000000 _resolvingUnmanagedDll
+        0000000000000000  4000ea5       18                       0 instance 0000000000000000 _resolving
+        00007ff7c9d36850  4000ea6       20 ...Private.CoreLib]]  0 instance 000001c2800101b8 _unloading
+        00007ff7c9a74748  4000ea7       28        System.String  0 instance 0000000000000000 _name
+        00007ff7c9a427f0  4000ea8       30        System.IntPtr  1 instance 000001C2FA21DD50 _nativeAssemblyLoadContext
+        00007ff7c9a1c7e0  4000ea9       38         System.Int64  1 instance                0 _id
+        00007ff7c9ac57b8  4000eaa       40         System.Int32  1 instance                0 _state
+        00007ff7c9a107b8  4000eab       44       System.Boolean  1 instance                1 _isCollectible
+        00007ff7c9cb4070  4000ea1      b08 ...Private.CoreLib]]  0   static 000001c28000d090 s_allContexts
+        00007ff7c9a1c7e0  4000ea2      970         System.Int64  1   static                1 s_nextId
+        0000000000000000  4000eac      b10 ...yLoadEventHandler  0   static 0000000000000000 AssemblyLoad
+        0000000000000000  4000ead      b18 ...solveEventHandler  0   static 0000000000000000 TypeResolve
+        0000000000000000  4000eae      b20 ...solveEventHandler  0   static 0000000000000000 ResourceResolve
+        0000000000000000  4000eaf      b28 ...solveEventHandler  0   static 0000000000000000 AssemblyResolve
+        0000000000000000  4000eb0      b30                       0   static 0000000000000000 s_asyncLocalCurrent
+        00007ff7c9cb26d0  4000001       48 ...ependencyResolver  0 instance 000001c28000d1c0 _resolver
+
+\\
+
 COMMAND: dumpasync.
 DumpAsync [-addr <Object Address>]
           [-mt <MethodTable address>]
index 264f969ce98a95237c6a18bc3b7226599458885a..7611188937534dbc4cdc72ae04c200176b08651d 100644 (file)
@@ -1636,6 +1636,46 @@ HRESULT PrintObj(TADDR taObj, BOOL bPrintFields = TRUE)
     return S_OK;
 }
 
+HRESULT PrintALC(TADDR taObj)
+{
+    if (!sos::IsObject(taObj, true))
+    {
+        ExtOut("<Note: this object has an invalid CLASS field>\n");
+    }
+
+    DacpObjectData objData;
+    HRESULT Status;
+    if ((Status=objData.Request(g_sos, TO_CDADDR(taObj))) != S_OK)
+    {
+        ExtOut("Invalid object\n");
+        return Status;
+    }
+
+    if (objData.ObjectType==OBJ_FREE)
+    {
+        ExtOut("Free Object\n");
+        DWORD_PTR size = (DWORD_PTR)objData.Size;
+        ExtOut("Size:        %" POINTERSIZE_TYPE "d(0x%" POINTERSIZE_TYPE "x) bytes\n", size, size);
+        return S_OK;
+    }
+
+    CLRDATA_ADDRESS assemblyLoadContext;
+    ReleaseHolder<ISOSDacInterface8> sos8;
+    if (SUCCEEDED(Status = g_sos->QueryInterface(__uuidof(ISOSDacInterface8), &sos8)))
+    {
+        Status = sos8->GetAssemblyLoadContext(objData.MethodTable, &assemblyLoadContext);
+    }
+
+    if (assemblyLoadContext == NULL)
+    {
+        ExtOut("Name:        System.Runtime.Loader.DefaultAssemblyLoadContext\n");
+        ExtOut("The managed instance of this context doesn't exist yet\n");
+        return S_OK;
+    }
+
+    return PrintObj(assemblyLoadContext);
+}
+
 BOOL IndicesInRange (DWORD * indices, DWORD * lowerBounds, DWORD * bounds, DWORD rank)
 {
     int i = 0;
@@ -2068,6 +2108,58 @@ DECLARE_API(DumpObj)
     return Status;
 }
 
+/**********************************************************************\
+* Routine Description:                                                 *
+*                                                                      *
+*    This function is called to dump the contents of an object from a  *
+*    given address                                                     *
+*                                                                      *
+\**********************************************************************/
+DECLARE_API(DumpALC)
+{
+    INIT_API();
+
+    MINIDUMP_NOT_SUPPORTED();
+
+    BOOL dml = FALSE;
+    StringHolder str_Object;
+    CMDOption option[] =
+    {   // name, vptr, type, hasValue
+#ifndef FEATURE_PAL
+        {"/d", &dml, COBOOL, FALSE},
+#endif
+    };
+    CMDValue arg[] =
+    {   // vptr, type
+        {&str_Object.data, COSTRING}
+    };
+    size_t nArg;
+    if (!GetCMDOption(args, option, _countof(option), arg, _countof(arg), &nArg))
+    {
+        return Status;
+    }
+
+    DWORD_PTR p_Object = GetExpression(str_Object.data);
+    EnableDMLHolder dmlHolder(dml);
+    if (p_Object == 0)
+    {
+        ExtOut("Invalid parameter %s\n", args);
+        return Status;
+    }
+
+    try
+    {
+        Status = PrintALC(p_Object);
+    }
+    catch(const sos::Exception &e)
+    {
+        ExtOut("%s\n", e.what());
+        return E_FAIL;
+    }
+
+    return Status;
+}
+
 /**********************************************************************\
 * Routine Description:                                                 *
 *                                                                      *
index e4cb8f1fa7e79463457de4b03b5a61ec669ec7c9..4e1a19e8850cbb8269261a42eec5d6999a7cefed 100644 (file)
@@ -135,6 +135,7 @@ sosCommandInitialize(lldb::SBDebugger debugger)
     interpreter.AddCommand("clrthreads", new sosCommand("Threads"), "List the managed threads running.");
     interpreter.AddCommand("clru", new sosCommand("u"), "Displays an annotated disassembly of a managed method.");
     interpreter.AddCommand("dbgout", new sosCommand("dbgout"), "Enable/disable (-off) internal SOS logging.");
+    interpreter.AddCommand("dumpalc", new sosCommand("DumpALC"), "Displays details about a collectible AssemblyLoadContext to which the specified object is loaded.");
     interpreter.AddCommand("dumparray", new sosCommand("DumpArray"), "Displays details about a managed array.");
     interpreter.AddCommand("dumpasync", new sosCommand("DumpAsync"), "Displays info about async state machines on the garbage-collected heap.");
     interpreter.AddCommand("dumpassembly", new sosCommand("DumpAssembly"), "Displays details about an assembly.");
index b088aeca1dd658472d5b689df97e4bd94b0a34bf..4b1093413f14444a1c6a0e7dda23e78fc073f32d 100644 (file)
@@ -13,6 +13,7 @@ namespace Microsoft.Diagnostics.Tools.Dump
     [Command(Name = "clrstack",         AliasExpansion = "ClrStack",            Help = "Provides a stack trace of managed code only.")]
     [Command(Name = "clrthreads",       AliasExpansion = "Threads",             Help = "List the managed threads running.")]
     [Command(Name = "dbgout",           AliasExpansion = "dbgout",              Help = "Enable/disable (-off) internal SOS logging.")]
+    [Command(Name = "dumpalc",          AliasExpansion = "DumpALC",             Help = "Displays details about a collectible AssemblyLoadContext into which the specified object is loaded.")]
     [Command(Name = "dumparray",        AliasExpansion = "DumpArray",           Help = "Displays details about a managed array.")]
     [Command(Name = "dumpasync",        AliasExpansion = "DumpAsync",           Help = "Displays info about async state machines on the garbage-collected heap.")]
     [Command(Name = "dumpassembly",     AliasExpansion = "DumpAssembly",        Help = "Displays details about an assembly.")]
index e29ef5692f0a3b2892b8a9a06071400a75de39f8..4b609856629aa1ad11fbcf6b1a20d7c0dbd15bbb 100644 (file)
@@ -407,4 +407,6 @@ interface ISOSDacInterface8 : IUnknown
     // SVR
     HRESULT GetGenerationTableSvr(CLRDATA_ADDRESS heapAddr, unsigned int cGenerations, struct DacpGenerationData *pGenerationData, unsigned int *pNeeded);
     HRESULT GetFinalizationFillPointersSvr(CLRDATA_ADDRESS heapAddr, unsigned int cFillPointers, CLRDATA_ADDRESS *pFinalizationFillPointers, unsigned int *pNeeded);
+
+    HRESULT GetAssemblyLoadContext(CLRDATA_ADDRESS methodTable, CLRDATA_ADDRESS* assemblyLoadContext);
 }
index ba31ed239b5ab1e222cc8c424cfbb0f0fe19353a..3d9e62aa8596f97f8dd14bb90ba30d94d3d89cfa 100644 (file)
@@ -98,6 +98,9 @@ MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface6,0x11206399,0x4b66,0x4edb,0x98,0xea,0
 MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface7,0xc1020dde,0xfe98,0x4536,0xa5,0x3b,0xf3,0x5a,0x74,0xc3,0x27,0xeb);
 
 
+MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface8,0xc12f35a9,0xe55c,0x4520,0xa8,0x94,0xb3,0xdc,0x51,0x65,0xdf,0xce);
+
+
 #undef MIDL_DEFINE_GUID
 
 #ifdef __cplusplus
index 21040e2ebe7758b561b4a3b109d55ba2fe630a50..7dcbfe28f3d694a8e2313328eb5a91bb68475b8c 100644 (file)
@@ -2548,6 +2548,9 @@ EXTERN_C const IID IID_ISOSDacInterface8;
             CLRDATA_ADDRESS *pFinalizationFillPointers,
             unsigned int *pNeeded) = 0;
 
+        virtual HRESULT STDMETHODCALLTYPE GetAssemblyLoadContext(
+            CLRDATA_ADDRESS methodTable,
+            CLRDATA_ADDRESS *assemblyLoadContext) = 0;
     };
 
 
@@ -2599,6 +2602,11 @@ EXTERN_C const IID IID_ISOSDacInterface8;
             CLRDATA_ADDRESS *pFinalizationFillPointers,
             unsigned int *pNeeded);
 
+        HRESULT ( STDMETHODCALLTYPE *GetAssemblyLoadContext )(
+            ISOSDacInterface8 * This,
+            CLRDATA_ADDRESS methodTable,
+            CLRDATA_ADDRESS *assemblyLoadContext);
+
         END_INTERFACE
     } ISOSDacInterface8Vtbl;
 
@@ -2637,6 +2645,9 @@ EXTERN_C const IID IID_ISOSDacInterface8;
 #define ISOSDacInterface8_GetFinalizationFillPointersSvr(This,heapAddr,cFillPointers,pFinalizationFillPointers,pNeeded) \
     ( (This)->lpVtbl -> GetFinalizationFillPointersSvr(This,heapAddr,cFillPointers,pFinalizationFillPointers,pNeeded) )
 
+#define ISOSDacInterface8_GetAssemblyLoadContext(This,methodTable,assemblyLoadContext) \
+    ( (This)->lpVtbl -> GetAssemblyLoadContext(This,methodTable,assemblyLoadContext) )
+
 #endif /* COBJMACROS */