Enable more SOS commands for Linux/MacOS (#3233)
authorMike McLaughlin <mikem@microsoft.com>
Fri, 29 Jul 2022 18:41:58 +0000 (11:41 -0700)
committerGitHub <noreply@github.com>
Fri, 29 Jul 2022 18:41:58 +0000 (11:41 -0700)
Enable more SOS commands for Linux/MacOS

Allows more SOS on Linux/MacOS and Linux core dumps on Windows under Windbg.

Commands enabled for Linux/MacOS on lldb, windbg and dotnet-dump:

DumpSig
DumpSigElem
DumpRuntimeTypes
VerifyHeap
AnalyzeOOM
VerifyObj
ListNearObj
GCHeapStat
ThreadPool
EHInfo
GCInfo
ObjSize
FindRoots

Under dotnet-dump and lldb this commands are lowercase.

Issue: https://github.com/dotnet/diagnostics/issues/3169

Fix invalid formatting char problems on Windows on a few of the commands.

Fix dumpgcdata for server GCs

Fix verifyheap failures

Fix GCHeapTraverse for empty POH

Co-authored-by: Andrew Au <andrewau@microsoft.com>
14 files changed:
src/SOS/SOS.Hosting/Commands/SOSCommand.cs
src/SOS/SOS.UnitTests/Scripts/GCPOH.script
src/SOS/SOS.UnitTests/Scripts/OtherCommands.script
src/SOS/Strike/eeheap.cpp
src/SOS/Strike/sos.cpp
src/SOS/Strike/sos.h
src/SOS/Strike/sos_unixexports.src
src/SOS/Strike/sosdocsunix.txt
src/SOS/Strike/strike.cpp
src/SOS/Strike/util.cpp
src/SOS/Strike/util.h
src/SOS/lldbplugin/soscommand.cpp
src/shared/dbgutil/elfreader.cpp
src/shared/inc/gcdesc.h

index 8904b3a5595a8817a1ed118bb9ba82674d47fb02..c37b4f7b1e07d27870be58204e98f94a562c7fdb 100644 (file)
@@ -10,6 +10,7 @@ using System.Linq;
 
 namespace SOS.Hosting
 {
+    [Command(Name = "analyzeoom",       DefaultOptions = "AnalyzeOOM",          Help = "Displays the info of the last OOM occurred on an allocation request to the GC heap.")]
     [Command(Name = "clrstack",         DefaultOptions = "ClrStack",            Help = "Provides a stack trace of managed code only.")]
     [Command(Name = "clrthreads",       DefaultOptions = "Threads",             Help = "List the managed threads running.")]
     [Command(Name = "dbgout",           DefaultOptions = "dbgout",              Help = "Enable/disable (-off) internal SOS logging.")]
@@ -19,6 +20,7 @@ namespace SOS.Hosting
     [Command(Name = "dumpclass",        DefaultOptions = "DumpClass",           Help = "Displays information about a EE class structure at the specified address.")]
     [Command(Name = "dumpdelegate",     DefaultOptions = "DumpDelegate",        Help = "Displays information about a delegate.")]
     [Command(Name = "dumpdomain",       DefaultOptions = "DumpDomain",          Help = "Displays information all the AppDomains and all assemblies within the domains.")]
+    [Command(Name = "dumpgcdata",       DefaultOptions = "DumpGCData",          Help = "Displays information about the GC data.")]
     [Command(Name = "dumpheap",         DefaultOptions = "DumpHeap",            Help = "Displays info about the garbage-collected heap and collection statistics about objects.")]
     [Command(Name = "dumpil",           DefaultOptions = "DumpIL",              Help = "Displays the Microsoft intermediate language (MSIL) that is associated with a managed method.")]
     [Command(Name = "dumplog",          DefaultOptions = "DumpLog",             Help = "Writes the contents of an in-memory stress log to the specified file.")]
@@ -26,37 +28,44 @@ namespace SOS.Hosting
     [Command(Name = "dumpmodule",       DefaultOptions = "DumpModule",          Help = "Displays information about a EE module structure at the specified address.")]
     [Command(Name = "dumpmt",           DefaultOptions = "DumpMT",              Help = "Displays information about a method table at the specified address.")]
     [Command(Name = "dumpobj",          DefaultOptions = "DumpObj",             Aliases = new string[] { "do" }, Help = "Displays info about an object at the specified address.")]
-    [Command(Name = "dumpvc",           DefaultOptions = "DumpVC",              Help = "Displays info about the fields of a value class.")]
+    [Command(Name = "dumpruntimetypes", DefaultOptions = "DumpRuntimeTypes",    Help = "Finds all System.RuntimeType objects in the gc heap and prints the type name and MethodTable they refer too.")]
+    [Command(Name = "dumpsig",          DefaultOptions = "DumpSig",             Help = "This command dumps the signature of a method or field given by <sigaddr> <moduleaddr>.")]
+    [Command(Name = "dumpsigelem",      DefaultOptions = "DumpSigElem",         Help = "This command dumps a single element of a signature object.")]
     [Command(Name = "dumpstackobjects", DefaultOptions = "DumpStackObjects",    Aliases = new string[] { "dso" }, Help = "Displays all managed objects found within the bounds of the current stack.")]
+    [Command(Name = "dumpvc",           DefaultOptions = "DumpVC",              Help = "Displays info about the fields of a value class.")]
     [Command(Name = "eeheap",           DefaultOptions = "EEHeap",              Help = "Displays info about process memory consumed by internal runtime data structures.")]
     [Command(Name = "eeversion",        DefaultOptions = "EEVersion",           Help = "Displays information about the runtime version.")]
+    [Command(Name = "ehinfo",           DefaultOptions = "EHInfo",              Help = "Displays the exception handling blocks in a jitted method.")]
     [Command(Name = "finalizequeue",    DefaultOptions = "FinalizeQueue",       Help = "Displays all objects registered for finalization.")]
+    [Command(Name = "findappdomain",    DefaultOptions = "FindAppDomain",       Help = "Attempts to resolve the AppDomain of a GC object.")]
+    [Command(Name = "gchandles",        DefaultOptions = "GCHandles",           Help = "Provides statistics about GCHandles in the process.")]
+    [Command(Name = "gcheapstat",       DefaultOptions = "GCHeapStat",          Help = "Display various GC heap stats.")]
     [Command(Name = "gcroot",           DefaultOptions = "GCRoot",              Help = "Displays info about references (or roots) to an object at the specified address.")]
+    [Command(Name = "gcinfo",           DefaultOptions = "GCInfo",              Help = "Displays info JIT GC encoding for a method.")]
     [Command(Name = "gcwhere",          DefaultOptions = "GCWhere",             Help = "Displays the location in the GC heap of the argument passed in.")]
-    [Command(Name = "ip2md",            DefaultOptions = "IP2MD",               Help = "Displays the MethodDesc structure at the specified address in code that has been JIT-compiled.")]
-    [Command(Name = "name2ee",          DefaultOptions = "Name2EE",             Help = "Displays the MethodTable structure and EEClass structure for the specified type or method in the specified module.")]
-    [Command(Name = "printexception",   DefaultOptions = "PrintException",      Aliases = new string[] { "pe" }, Help = "Displays and formats fields of any object derived from the Exception class at the specified address.")]
-    [Command(Name = "syncblk",          DefaultOptions = "SyncBlk",             Help = "Displays the SyncBlock holder info.")]
     [Command(Name = "histclear",        DefaultOptions = "HistClear",           Help = "Releases any resources used by the family of Hist commands.")]
     [Command(Name = "histinit",         DefaultOptions = "HistInit",            Help = "Initializes the SOS structures from the stress log saved in the debuggee.")]
     [Command(Name = "histobj",          DefaultOptions = "HistObj",             Help = "Examines all stress log relocation records and displays the chain of garbage collection relocations that may have led to the address passed in as an argument.")]
     [Command(Name = "histobjfind",      DefaultOptions = "HistObjFind",         Help = "Displays all the log entries that reference an object at the specified address.")]
     [Command(Name = "histroot",         DefaultOptions = "HistRoot",            Help = "Displays information related to both promotions and relocations of the specified root.")]
-    [Command(Name = "verifyheap",       DefaultOptions = "VerifyHeap",          Help = "Checks the GC heap for signs of corruption.")]
-    [Command(Name = "threadpool",       DefaultOptions = "ThreadPool",          Help = "Lists basic information about the thread pool.")]
+    [Command(Name = "histstats",        DefaultOptions = "HistStats",           Help = "Displays stress log stats.")]
+    [Command(Name = "ip2md",            DefaultOptions = "IP2MD",               Help = "Displays the MethodDesc structure at the specified address in code that has been JIT-compiled.")]
+    [Command(Name = "listnearobj",      DefaultOptions = "ListNearObj",         Help = "Displays the object preceding and succeeding the address specified.")]
+    [Command(Name = "name2ee",          DefaultOptions = "Name2EE",             Help = "Displays the MethodTable structure and EEClass structure for the specified type or method in the specified module.")]
+    [Command(Name = "objsize",          DefaultOptions = "ObjSize",             Help = "Lists the sizes of the all the objects found on managed threads.")]
+    [Command(Name = "pathto",           DefaultOptions = "PathTo",              Help = "Displays the GC path from <root> to <target>.")]
+    [Command(Name = "printexception",   DefaultOptions = "PrintException",      Aliases = new string[] { "pe" }, Help = "Displays and formats fields of any object derived from the Exception class at the specified address.")]
     [Command(Name = "soshelp",          DefaultOptions = "Help",                Help = "Displays help for a specific SOS command.")]
+    [Command(Name = "syncblk",          DefaultOptions = "SyncBlk",             Help = "Displays the SyncBlock holder info.")]
+    [Command(Name = "threadpool",       DefaultOptions = "ThreadPool",          Help = "Lists basic information about the thread pool.")]
+    [Command(Name = "verifyheap",       DefaultOptions = "VerifyHeap",          Help = "Checks the GC heap for signs of corruption.")]
+    [Command(Name = "verifyobj",        DefaultOptions = "VerifyObj",           Help = "Checks the object for signs of corruption.")]
     [Command(Name = "dumprcw",          DefaultOptions = "DumpRCW",             Platform = CommandPlatform.Windows, Help = "Displays information about a Runtime Callable Wrapper.")]
     [Command(Name = "dumpccw",          DefaultOptions = "DumpCCW",             Platform = CommandPlatform.Windows, Help = "Displays information about a COM Callable Wrapper.")]
     [Command(Name = "dumppermissionset",DefaultOptions = "DumpPermissionSet",   Platform = CommandPlatform.Windows, Help = "Displays a PermissionSet object (debug build only).")]
     [Command(Name = "traverseheap",     DefaultOptions = "TraverseHeap",        Platform = CommandPlatform.Windows, Help = "Writes out a file in a format understood by the CLR Profiler.")]
-    [Command(Name = "analyzeoom",       DefaultOptions = "AnalyzeOOM",          Platform = CommandPlatform.Windows, Help = "Displays the info of the last OOM occurred on an allocation request to the GC heap.")]
-    [Command(Name = "verifyobj",        DefaultOptions = "VerifyObj",           Platform = CommandPlatform.Windows, Help = "Checks the object for signs of corruption.")]
-    [Command(Name = "listnearobj",      DefaultOptions = "ListNearObj",         Platform = CommandPlatform.Windows, Help = "Displays the object preceding and succeeding the address specified.")]
-    [Command(Name = "gcheapstat",       DefaultOptions = "GCHeapStat",          Platform = CommandPlatform.Windows, Help = "Display various GC heap stats.")]
     [Command(Name = "watsonbuckets",    DefaultOptions = "WatsonBuckets",       Platform = CommandPlatform.Windows, Help = "Displays the Watson buckets.")]
     [Command(Name = "comstate",         DefaultOptions = "COMState",            Platform = CommandPlatform.Windows, Help = "Lists the COM apartment model for each thread.")]
-    [Command(Name = "gchandles",        DefaultOptions = "GCHandles",           Help = "Provides statistics about GCHandles in the process.")]
-    [Command(Name = "objsize",          DefaultOptions = "ObjSize",             Help = "Lists the sizes of the all the objects found on managed threads.")]
     [Command(Name = "gchandleleaks",    DefaultOptions = "GCHandleLeaks",       Platform = CommandPlatform.Windows, Help = "Helps in tracking down GCHandle leaks")]
     public class SOSCommand : CommandBase
     {
index ea211230abb0dab7a8358805ed29f45221fe82a6..fb0e5138c1483107e7ed7e344a0ba96bf61ae4b4 100644 (file)
@@ -24,6 +24,8 @@ SOSCOMMAND:DumpObj <POUT>\w+\s+(<HEXVAL>)\s+(System.Byte\[\]!\$0_)*System.Byte\[
 VERIFY:\s+Name:        System.Byte\[\]\s+
 VERIFY:\s+Array:       Rank 1, Number of elements 100, Type Byte\s+
 
+SOSCOMMAND:ObjSize <PREVPOUT>
+
 SOSCOMMAND:GCWhere <PREVPOUT>
 # we care that the Gen is 4 (POH)
 VERIFY:<HEXVAL>\s+4\s+\d\s+<HEXVAL>\s+<HEXVAL>\s+<HEXVAL>\s+0x<HEXVAL>\s*\(\d+\)
@@ -36,6 +38,11 @@ SOSCOMMAND:GCRoot -all <PREVPOUT>
 VERIFY:.*Thread <HEXVAL>:
 VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+GCPOH\.Main\(\)\s+\[.*[Gg][Cc][Pp][Oo][Hh]\.cs\s+@\s+19\]\s+
 
+SOSCOMMAND:VerifyHeap
+VERIFY:\s*No heap corruption detected.\s*
+
+SOSCOMMAND:GCHeapStat
+
 SOSCOMMAND:DumpHeap
 VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+<DECVAL>\s+
 
index c26430486baab9330171ff3789d21ec05893dcb8..76470093edac59f64882c70d799ca7d94fc30672 100644 (file)
@@ -68,6 +68,10 @@ VERIFY:\s*<DECVAL>\s+0x<HEXVAL>\s+\(<DECVAL>\)\s+
 EXTCOMMAND:registers
 VERIFY:\s*([r|e]ip|pc) = 0x<HEXVAL>\s+
 
+SOSCOMMAND:ThreadPool
+
+SOSCOMMAND:VerifyHeap
+
 SOSCOMMAND:DumpHeap
 VERIFY:\s+Address\s+MT\s+Size\s+
 VERIFY:\s+<HEXVAL>\s+<HEXVAL>\s+<DECVAL>.*
@@ -131,3 +135,9 @@ VERIFY:\s*Total\s+<DECVAL>
 VERIFY:\s*CCW\s+<DECVAL>
 VERIFY:\s*RCW\s+<DECVAL>
 ENDIF:WINDOWS
+
+SOSCOMMAND:GCHandles
+
+SOSCOMMAND:DumpGCData
+
+SOSCOMMAND:DumpRuntimeTypes
index 7bb21cf8b09e64fc46576911674470d9a34d419c..53a7d626216ed883d9d0e01f03562391a0314f56 100644 (file)
@@ -12,7 +12,6 @@
 #include "safemath.h"
 #include "releaseholder.h"
 
-
 // This is the increment for the segment lookup data
 const int nSegLookupStgIncrement = 100;
 
@@ -849,7 +848,6 @@ BOOL GCObjInHeap(TADDR taddrObj, const GCHeapDetails &heap, TADDR_SEGINFO& rngSe
     return FALSE;
 }
 
-#ifndef FEATURE_PAL
 // this function updates genUsage to reflect statistics from the range defined by [start, end)
 void GCGenUsageStats(TADDR start, TADDR alloc_end, TADDR commit_end, const std::unordered_set<TADDR> &liveObjs,
     const GCHeapDetails &heap, BOOL bLarge, BOOL bPinned, const AllocInfo *pAllocInfo, GenUsageStat *genUsage)
@@ -943,7 +941,6 @@ void GCGenUsageStats(TADDR start, TADDR alloc_end, TADDR commit_end, const std::
         }
     }
 }
-#endif // !FEATURE_PAL
 
 BOOL GCHeapUsageStats(const GCHeapDetails& heap, BOOL bIncUnreachable, HeapUsageStat *hpUsage)
 {
@@ -977,9 +974,7 @@ BOOL GCHeapUsageStats(const GCHeapDetails& heap, BOOL bIncUnreachable, HeapUsage
                     ExtErr("Error requesting heap segment %p\n", SOS_PTR(taddrSeg));
                     return FALSE;
                 }
-#ifndef FEATURE_PAL
                 GCGenUsageStats((TADDR)dacpSeg.mem, (TADDR)dacpSeg.highAllocMark, (TADDR)dacpSeg.committed, liveObjs, heap, FALSE, FALSE, &allocInfo, &hpUsage->genUsage[n]);
-#endif
                 taddrSeg = (TADDR)dacpSeg.next;
             }
         }
@@ -989,7 +984,6 @@ BOOL GCHeapUsageStats(const GCHeapDetails& heap, BOOL bIncUnreachable, HeapUsage
         // 1. Start with small object segments
         taddrSeg = (TADDR)heap.generation_table[GetMaxGeneration()].start_segment;
 
-#ifndef FEATURE_PAL
         // 1a. enumerate all non-ephemeral segments
         while (taddrSeg != (TADDR)heap.generation_table[0].start_segment)
         {
@@ -1004,7 +998,6 @@ BOOL GCHeapUsageStats(const GCHeapDetails& heap, BOOL bIncUnreachable, HeapUsage
             GCGenUsageStats((TADDR)dacpSeg.mem, (TADDR)dacpSeg.allocated, (TADDR)dacpSeg.committed, liveObjs, heap, FALSE, FALSE, &allocInfo, &hpUsage->genUsage[2]);
             taddrSeg = (TADDR)dacpSeg.next;
         }
-#endif
 
         // 1b. now handle the ephemeral segment
         if (dacpSeg.Request(g_sos, taddrSeg, heap.original_heap_details) != S_OK)
@@ -1028,9 +1021,7 @@ BOOL GCHeapUsageStats(const GCHeapDetails& heap, BOOL bIncUnreachable, HeapUsage
                 startGen = TO_TADDR(heap.generation_table[n].allocation_start);
             }
 
-#ifndef FEATURE_PAL
             GCGenUsageStats(startGen, endGen, (TADDR)dacpSeg.committed, liveObjs, heap, FALSE, FALSE, &allocInfo, &hpUsage->genUsage[n]);
-#endif
             endGen = startGen;
         }
     }
@@ -1048,9 +1039,7 @@ BOOL GCHeapUsageStats(const GCHeapDetails& heap, BOOL bIncUnreachable, HeapUsage
             return FALSE;
         }
 
-#ifndef FEATURE_PAL
         GCGenUsageStats((TADDR) dacpSeg.mem, (TADDR) dacpSeg.allocated, (TADDR) dacpSeg.committed, liveObjs, heap, TRUE, FALSE, NULL, &hpUsage->genUsage[3]);
-#endif
         taddrSeg = (TADDR)dacpSeg.next;
     }
 
@@ -1069,9 +1058,7 @@ BOOL GCHeapUsageStats(const GCHeapDetails& heap, BOOL bIncUnreachable, HeapUsage
                 return FALSE;
             }
 
-#ifndef FEATURE_PAL
             GCGenUsageStats((TADDR) dacpSeg.mem, (TADDR) dacpSeg.allocated, (TADDR) dacpSeg.committed, liveObjs, heap, FALSE, TRUE, NULL, &hpUsage->genUsage[4]);
-#endif
             taddrSeg = (TADDR)dacpSeg.next;
         }
     }
@@ -1197,7 +1184,7 @@ void GatherOneHeapFinalization(DacpGcHeapDetails& heapDetails, HeapStat *stat, B
                 SOS_PTR(SegQueueLimit(heapDetails,gen_segment(m))));
         }
     }
-#ifndef FEATURE_PAL
+
     if (bAllReady)
     {
         if (!bShort)
@@ -1210,7 +1197,6 @@ void GatherOneHeapFinalization(DacpGcHeapDetails& heapDetails, HeapStat *stat, B
 
         PrintNotReachableInRange(rngStart, rngEnd, TRUE, bAllReady ? stat : NULL, bShort);
     }
-#endif
 
     if (!bShort)
     {
@@ -1585,6 +1571,7 @@ BOOL GCHeapTraverse(const GCHeapDetails &heap, AllocInfo* pallocInfo, VISITGCHEA
                 }
 
                 dwAddrCurrObj = (DWORD_PTR)segment.mem;
+                continue;
             }
             else
             {
index f2052cfa2ef726930446e19399a0e0b11b416ec2..5764a86dd4e62b2311f1c78f570b8ec7d74212fb 100644 (file)
@@ -4,21 +4,9 @@
 
 #include "strike.h"
 #include "util.h"
-
 #include "sos.h"
-
-
-#ifdef _ASSERTE
-#undef _ASSERTE
-#endif
-
-#define _ASSERTE(a) {;}
-
 #include "gcdesc.h"
 
-
-#undef _ASSERTE
-
 namespace sos
 {
     template <class T>
@@ -505,7 +493,7 @@ namespace sos
                 int entries = 0;
 
                 if (FAILED(MOVE(entries, mt-sizeof(TADDR))))
-                    Throw<DataRead>("Failed to request number of entries.");
+                    Throw<DataRead>("Failed to request number of entries for %p MT %p", mObject, mt);
 
                 // array of vc?
                 if (entries < 0)
index 98a71b678e4f61ba32019e2658ba8a5a371b7dc4..2a58703c85e865d98d4d15accd6c6e82b3b2eb03 100644 (file)
@@ -721,7 +721,7 @@ namespace sos
         inline const SyncBlkIterator &operator++()
         {
             SOS_Assert(mCurr <= mTotal);
-            mSyncBlk = ++mCurr;
+            mSyncBlk = mCurr++;
 
             return *this;
         }
index 7928b2dfe6c54ec91be1c6e672d0010620e6aa5d..35bd51fa0c9025423226cbaf3c8ee018b61eb3a2 100644 (file)
@@ -2,6 +2,7 @@
 ; The .NET Foundation licenses this file to you under the MIT license.
 ; See the LICENSE file in the project root for more information.
 
+AnalyzeOOM
 bpmd
 clrmodules
 ClrStack
@@ -29,15 +30,17 @@ DumpStackObjects
 DumpVC
 EEHeap
 EEVersion
-GCWhere
 EEStack
 EHInfo
 ext
 FinalizeQueue
 FindAppDomain
+FindRoots
 GCHandles
+GCHeapStat
 GCInfo
 GCRoot
+GCWhere
 Help
 HistClear
 HistInit
@@ -46,17 +49,18 @@ HistObjFind
 HistRoot
 HistStats
 IP2MD
+ListNearObj
 logging
 Name2EE
 ObjSize
 PrintException
 PathTo
+runtimes
 StopOnCatch
 SetClrPath
 SetSymbolServer
 SOSFlush
 SOSStatus
-runtimes
 SuppressJitOptimization
 SyncBlk
 Threads
@@ -65,6 +69,7 @@ ThreadState
 Token2EE
 u
 VerifyHeap
+VerifyObj
 
 SOSInitializeByHost
 SOSUninitializeByHost
index 11122de4f80c0c5642dd5e3013b823a95edfcc6b..6eb004882bb71d8dcde73ac17a6bc426e539cfa0 100644 (file)
@@ -32,22 +32,22 @@ DumpHeap (dumpheap)                EEStack (eestack)
 DumpVC                             ClrStack (clrstack)
 FinalizeQueue (finalizequeue)      GCInfo
 GCRoot (gcroot)                    EHInfo
-ObjSize                            bpmd (bpmd)
+ObjSize (objsize)                  bpmd (bpmd)
 PrintException (pe)
                                    
 Examining CLR data structures      Diagnostic Utilities
 -----------------------------      -----------------------------
 DumpDomain (dumpdomain)            VerifyHeap
 EEHeap (eeheap)                    FindAppDomain          
-Name2EE (name2ee)                  GCHandles
-SyncBlk (syncblk)                  DumpLog (dumplog)
-DumpMT (dumpmt)                    SuppressJitOptimization
-DumpClass (dumpclass)              ThreadPool (threadpool)
-DumpMD (dumpmd)                    
-Token2EE                           
+Name2EE (name2ee)                  DumpLog (dumplog)
+SyncBlk (syncblk)                  SuppressJitOptimization
+DumpMT (dumpmt)                    ThreadPool (threadpool)
+DumpClass (dumpclass)              AnalyzeOOM (analyzeoom)
+DumpMD (dumpmd)                    VerifyObj (verifyobj)
+Token2EE                           GCHandles (gchandles)
 DumpModule (dumpmodule)
 DumpAssembly (dumpassembly)
-DumpRuntimeTypes
+DumpRuntimeTypes (dumpruntimetypes)
 DumpIL (dumpil)
 DumpSig
 DumpSigElem
@@ -443,27 +443,6 @@ DumpVC is quite a specialized function. Some managed programs make heavy use
 of value classes, while others do not.
 \\
 
-COMMAND: finalizequeue
-FinalizeQueue [-detail] | [-allReady] [-short]
-
-Displays all objects registered for finalization.
-The "-detail" option displays extra information about any SyncBlocks that need
-to be cleaned up. This data structure is cached and cleaned up by the 
-finalizer thread when it runs.
-
-The "-allReady" option displays all objects that are ready for finalization,
-regardless of whether they are already marked by the garbage collection
-as such, or will be marked by the next garbage collection. The objects that
-are in the "ready for finalization" list are finalizable objects that are
-no longer rooted. This option can be very expensive, because it verifies
-whether all the objects in the finalizable queues are still rooted.
-
-The "-short" option limits the output to the address of each object. If it is
-used in conjunction with -allReady, it enumerates all objects that have
-a finalizer that are no longer rooted. If it is used independently, it lists
-all objects in the finalizable and "ready for finalization" queues.
-\\
-
 COMMAND: gcroot.
 GCRoot [-nostacks] [-all] <Object address>
 
@@ -526,6 +505,61 @@ number of roots can share a common subgraph, and that part will be reported in
 the size of all the roots that reference the subgraph.
 \\
 
+COMMAND: finalizequeue.
+FinalizeQueue [-detail] | [-allReady] [-short]
+
+This command lists the objects registered for finalization. Here is output from
+a simple program:
+
+    (lldb) finalizequeue
+    SyncBlocks to be cleaned up: 0
+    MTA Interfaces to be released: 0
+    STA Interfaces to be released: 1
+    generation 0 has 4 finalizable objects (0015bc90->0015bca0)
+    generation 1 has 0 finalizable objects (0015bc90->0015bc90)
+    generation 2 has 0 finalizable objects (0015bc90->0015bc90)
+    Ready for finalization 0 objects (0015bca0->0015bca0)
+    Statistics:
+          MT    Count TotalSize Class Name
+    5ba6cf78        1        24 Microsoft.Win32.SafeHandles.SafeFileHandle
+    5ba5db04        1        68 System.Threading.Thread
+    5ba73e28        2       112 System.IO.StreamWriter
+    Total 4 objects
+
+The GC heap is divided into generations, and objects are listed accordingly. We
+see that only generation 0 (the youngest generation) has any objects registered
+for finalization. The notation "(0015bc90->0015bca0)" means that if you look at
+memory in that range, you'll see the object pointers that are registered:
+
+0:000> dd 15bc90 15bca0-4
+0015bc90  00a743f4 00a79f00 00a7b3d8 00a7b47c
+
+You could run dumpobj on any of those pointers to learn more. In this example,
+there are no objects ready for finalization, presumably because they still have
+roots (You can use !GCRoot to find out). The statistics section provides a 
+higher-level summary of the objects registered for finalization. Note that 
+objects ready for finalization are also included in the statistics (if any).
+
+Specifying -short will inhibit any display related to SyncBlocks or RCWs.
+
+The arguments in detail:
+
+-allReady Specifying this argument will allow for the display of all objects 
+          that are ready for finalization, whether they are already marked by 
+          the GC as such, or whether the next GC will.  The objects that are 
+          not in the "Ready for finalization" list are finalizable objects that 
+          are no longer rooted.  This option can be very expensive, as it 
+          verifies whether all the objects in the finalizable queues are still 
+          rooted or not.
+-short    Limits the output to just the address of each object.  If used in 
+          conjunction with -allReady it enumerates all objects that have a 
+          finalizer that are no longer rooted.  If used independently it lists 
+          all objects in the finalizable and "ready for finalization" queues.
+-detail   Will display extra information on any SyncBlocks that need to be 
+          cleaned up, and on any RuntimeCallableWrappers (RCWs) that await 
+          cleanup.  Both of these data structures are cached and cleaned up by 
+          the finalizer thread when it gets a chance to run.
+\\
 COMMAND: pe.
 COMMAND: printexception.
 PrintException [-nested] [-lines] [-ccw] [<Exception object address>] [<CCW pointer>]
@@ -1622,6 +1656,7 @@ is a simple example of the output for a dynamic method:
   IL_0010: stloc.0
   IL_0011: ldloc.0
   IL_0012: ret
+
 \\
 
 COMMAND: verifyheap.
@@ -1662,6 +1697,127 @@ in the CLR. In user code, an error in constructing PInvoke calls can cause
 this problem, and running with Managed Debugging Assistants is advised. If that
 possibility is eliminated, consider contacting Microsoft Product Support for
 help.
+
+\\
+
+COMMAND: verifyobj.
+VerifyObj <object address>
+
+VerifyObj is a diagnostic tool that checks the object that is passed as an 
+argument for signs of corruption.
+
+    0:002> !verifyobj 028000ec
+    object 0x28000ec does not have valid method table
+
+    0:002> !verifyobj 0680017c 
+    object 0x680017c: bad member 00000001 at 06800184
+
+\\
+
+COMMAND: findroots.
+FindRoots -gen <N> | -gen any | <object address>
+
+The "-gen" form causes the debugger to break in the debuggee on the next 
+collection of the specified generation.  The effect is reset as soon as the 
+break occurs, in other words, if you need to break on the next collection you 
+would need to reissue the command.
+
+The last form of this command is meant to be used after the break caused by the 
+other forms has occurred.  Now the debuggee is in the right state for 
+findroots to be able to identify roots for objects from the current condemned 
+generations.
+
+FindRoots is a diagnostic command that is meant to answer the following 
+question:
+
+"I see that GCs are happening, however my objects have still not been 
+collected. Why? Who is holding onto them?"
+
+The process of answering the question would go something like this:
+
+1. Find out the generation of the object of interest using the gcwhere 
+command, say it is gen 1:
+    (lldb) gcwhere <object address>
+
+2. Instruct the runtime to stop the next time it collects that generation using 
+the findroots command:
+    findroots -gen 1
+    g
+
+3. When the next GC starts, and has proceeded past the mark phase a CLR 
+notification will cause a break in the debugger:
+    (fd0.ec4): CLR notification exception - code e0444143 (first chance)
+    CLR notification: GC - end of mark phase.
+        Condemned generation: 1.
+
+4. Now we can use the findroots <object address> to find out the cross 
+generational references to the object of interest.  In other words, even if the 
+object is not referenced by any "proper" root it may still be referenced by an 
+older object (from an older generation), from a generation that has not yet been 
+scheduled for collection.  At this point findroots will search those older 
+generations too, and report those roots.
+    (lldb) findroots 06808094 
+    older generations::Root:  068012f8(AAA.Test+a)->
+      06808094(AAA.Test+b)
+
+\\
+
+COMMAND: analyzeoom.
+AnalyzeOOM
+
+AnalyzeOOM displays the info of the last OOM occurred on an allocation request to
+the GC heap (in Server GC it displays OOM, if any, on each GC heap). 
+
+To see the managed exception(s) use the clrthreads command which will show you 
+managed exception(s), if any, on each managed thread. If you do see an 
+OutOfMemoryException exception you can use the !PrintException command on it.
+To get the full callstack use the "kb" command in the debugger for that thread.
+For example, to display thread 3's stack use ~3kb.
+
+OOM exceptions could be because of the following reasons:
+
+1) allocation request to GC heap 
+   in which case you will see JIT_New* on the call stack because managed code called new.
+2) other runtime allocation failure
+   for example, failure to expand the finalize queue when GC.ReRegisterForFinalize is
+   called.
+3) some other code you use throws a managed OOM exception 
+   for example, some .NET framework code converts a native OOM exception to managed 
+   and throws it.
+
+The !AnalyzeOOM command aims to help you with investigating 1) which is the most
+difficult because it requires some internal info from GC. The only exception is
+we don't support allocating objects larger than 2GB on CLR v2.0 or prior. And this
+command will not display any managed OOM because we will throw OOM right away 
+instead of even trying to allocate it on the GC heap.
+
+There are 2 legitimate scenarios where GC would return OOM to allocation requests - 
+one is if the process is running out of VM space to reserve a segment; the other
+is if the system is running out physical memory (+ page file if you have one) so
+GC can not commit memory it needs. You can look at these scenarios by using performance
+counters or debugger commands. For example for the former scenario the "!address 
+-summary" debugger command will show you the largest free region in the VM. For
+the latter scenario you can look at the "Memory% Committed Bytes In Use" see
+if you are running low on commit space. One important thing to keep in mind is
+when you do this kind of memory analysis it could an aftereffect and doesn't 
+completely agree with what this command tells you, in which case the command should
+be respected because it truly reflects what happened during GC.
+
+The other cases should be fairly obvious from the callstack.
+
+Sample output:
+
+0:011> !analyzeoom
+---------Heap 2 ---------
+Managed OOM occurred after GC #28 (Requested to allocate 1234 bytes)
+Reason: Didn't have enough memory to commit
+Detail: SOH: Didn't have enough memory to grow the internal GC datastructures (800000 bytes) - 
+        on GC entry available commit space was 500 MB
+---------Heap 4 ---------
+Managed OOM occurred after GC #12 (Requested to allocate 100000 bytes)
+Reason: Didn't have enough memory to allocate an LOH segment
+Detail: LOH: Failed to reserve memory (16777216 bytes)
+
 \\
 
 COMMAND: gcwhere.
@@ -1681,6 +1837,40 @@ the "size" is displayed as 0:
     0280003c 2    0   02800000 02800038 0282b740  0
 \\
 
+COMMAND: listnearobj.
+ListNearObj <object address>
+
+ListNearObj is a diagnostic tool that displays the object preceeding and 
+succeeding the address passed in:
+
+The command looks for the address in the GC heap that looks like a valid 
+beginning of a managed object (based on a valid method table) and the object 
+following the argument address.
+
+    0:002> listnearobj 028000ec
+    Before: 0x28000a4           72 (0x48      ) System.StackOverflowException
+    After:  0x2800134           72 (0x48      ) System.Threading.ThreadAbortException
+    Heap local consistency confirmed.
+
+    0:002> listnearobj 028000f0
+    Before: 0x28000ec           72 (0x48      ) System.ExecutionEngineException
+    After:  0x2800134           72 (0x48      ) System.Threading.ThreadAbortException
+    Heap local consistency confirmed.
+
+The command considers the heap as "locally consistent" if:
+    prev_obj_addr + prev_obj_size = arg_addr && arg_obj + arg_size = next_obj_addr
+OR
+    prev_obj_addr + prev_obj_size = next_obj_addr
+
+When the condition is not satisfied:
+
+    0:002> listnearobj 028000ec
+    Before: 0x28000a4           72 (0x48      ) System.StackOverflowException
+    After:  0x2800134           72 (0x48      ) System.Threading.ThreadAbortException
+    Heap local consistency not confirmed.
+
+\\
+
 COMMAND: dumplog.
 DumpLog [-addr <addressOfStressLog>] [<Filename>]
 
index 97ceb486437a4f0fe4cb76aa1851f3bf13ad3939..dd5177e95bb1d4a3bd5499e80568a6810c1790ea 100644 (file)
@@ -1044,7 +1044,6 @@ DECLARE_API(DumpSig)
     INIT_API();
 
     MINIDUMP_NOT_SUPPORTED();
-    ONLY_SUPPORTED_ON_WINDOWS_TARGET();
 
     //
     // Fetch arguments
@@ -1092,7 +1091,6 @@ DECLARE_API(DumpSigElem)
     INIT_API();
 
     MINIDUMP_NOT_SUPPORTED();
-    ONLY_SUPPORTED_ON_WINDOWS_TARGET();
 
     //
     // Fetch arguments
@@ -3940,7 +3938,6 @@ DECLARE_API(DumpRuntimeTypes)
 {
     INIT_API();
     MINIDUMP_NOT_SUPPORTED();
-    ONLY_SUPPORTED_ON_WINDOWS_TARGET();
 
     BOOL dml = FALSE;
 
@@ -3961,7 +3958,16 @@ DECLARE_API(DumpRuntimeTypes)
     PrintRuntimeTypeArgs pargs;
     ZeroMemory(&pargs, sizeof(PrintRuntimeTypeArgs));
 
-    GCHeapsTraverse(PrintRuntimeTypes, (LPVOID)&pargs);
+    try
+    {
+        GCHeapsTraverse(PrintRuntimeTypes, (LPVOID)&pargs);
+    }
+    catch(const sos::Exception &e)
+    {
+        ExtOut("%s\n", e.what());
+        return E_FAIL;
+    }
+
     return Status;
 }
 
@@ -4495,7 +4501,6 @@ DECLARE_API(VerifyHeap)
 {
     INIT_API();
     MINIDUMP_NOT_SUPPORTED();
-    ONLY_SUPPORTED_ON_WINDOWS_TARGET();
 
     if (!g_snapshot.Build())
     {
@@ -4539,8 +4544,6 @@ DECLARE_API(VerifyHeap)
     }
 }
 
-#ifndef FEATURE_PAL
-
 enum failure_get_memory
 {
     fgm_no_failure = 0,
@@ -4631,9 +4634,6 @@ DECLARE_API(AnalyzeOOM)
 {
     INIT_API();
     MINIDUMP_NOT_SUPPORTED();
-    ONLY_SUPPORTED_ON_WINDOWS_TARGET();
-
-#ifndef FEATURE_PAL
 
     if (!InitializeHeapData ())
     {
@@ -4699,17 +4699,12 @@ DECLARE_API(AnalyzeOOM)
     }
 
     return S_OK;
-#else
-    _ASSERTE(false);
-    return E_FAIL;
-#endif // FEATURE_PAL
 }
 
 DECLARE_API(VerifyObj)
 {
     INIT_API();
     MINIDUMP_NOT_SUPPORTED();
-    ONLY_SUPPORTED_ON_WINDOWS_TARGET();
 
     TADDR  taddrObj = 0;
     TADDR  taddrMT;
@@ -4748,10 +4743,17 @@ DECLARE_API(VerifyObj)
         ExtOut("Unable to build snapshot of the garbage collector state\n");
         goto Exit;
     }
+
+    try
     {
         GCHeapDetails *pheapDetails = g_snapshot.GetHeap(taddrObj);
         bValid = VerifyObject(*pheapDetails, taddrObj, taddrMT, objSize, TRUE);
     }
+    catch(const sos::Exception &e)
+    {
+        ExtOut("%s\n", e.what());
+        return E_FAIL;
+    }
 
 Exit:
     if (bValid)
@@ -4772,9 +4774,6 @@ DECLARE_API(ListNearObj)
 {
     INIT_API();
     MINIDUMP_NOT_SUPPORTED();
-    ONLY_SUPPORTED_ON_WINDOWS_TARGET();
-
-#if !defined(FEATURE_PAL)
 
     TADDR taddrArg = 0;
     TADDR taddrObj = 0;
@@ -4946,23 +4945,12 @@ DECLARE_API(ListNearObj)
     }
 
     return Status;
-
-#else
-
-    _ASSERTE(false);
-    return E_FAIL;
-
-#endif // FEATURE_PAL
 }
 
-
 DECLARE_API(GCHeapStat)
 {
     INIT_API();
     MINIDUMP_NOT_SUPPORTED();
-    ONLY_SUPPORTED_ON_WINDOWS_TARGET();
-
-#ifndef FEATURE_PAL
 
     BOOL bIncUnreachable = FALSE;
     BOOL dml = FALSE;
@@ -5026,7 +5014,7 @@ DECLARE_API(GCHeapStat)
                     pohUnrootedUsage, "%");
             }
 
-            ExtOut("\nCommitted space:");
+            ExtOut("\nCommitted space:\n");
             ExtOut("Heap%-4d %12" POINTERSIZE_TYPE "u %12" POINTERSIZE_TYPE "u %12" POINTERSIZE_TYPE "u %12" POINTERSIZE_TYPE "u %12" POINTERSIZE_TYPE "u\n", 0,
                 hpUsage.genUsage[0].committed, hpUsage.genUsage[1].committed,
                 hpUsage.genUsage[2].committed, hpUsage.genUsage[3].committed,
@@ -5066,7 +5054,9 @@ DECLARE_API(GCHeapStat)
         }
 
         // aggregate stats across heaps / generation
-        GenUsageStat genUsageStat[5] = {0, 0, 0, 0, 0};
+        GenUsageStat genUsageStat[5];
+        memset(genUsageStat, 0, sizeof(genUsageStat));
+
         bool hasPoh = false;
         for (DWORD n = 0; n < dwNHeaps; n ++)
         {
@@ -5151,17 +5141,8 @@ DECLARE_API(GCHeapStat)
     }
 
     return Status;
-
-#else
-
-    _ASSERTE(false);
-    return E_FAIL;
-
-#endif // FEATURE_PAL
 }
 
-#endif // FEATURE_PAL
-
 /**********************************************************************\
 * Routine Description:                                                 *
 *                                                                      *
@@ -8025,7 +8006,6 @@ DECLARE_API(ThreadPool)
 {
     INIT_API();
     MINIDUMP_NOT_SUPPORTED();
-    ONLY_SUPPORTED_ON_WINDOWS_TARGET();
 
     BOOL doHCDump = FALSE, doWorkItemDump = FALSE, dml = FALSE;
 
@@ -8610,7 +8590,6 @@ DECLARE_API(FindAppDomain)
 {
     INIT_API();
     MINIDUMP_NOT_SUPPORTED();
-    ONLY_SUPPORTED_ON_WINDOWS_TARGET();
 
     DWORD_PTR p_Object = NULL;
     BOOL dml = FALSE;
@@ -8879,7 +8858,6 @@ DECLARE_API(EHInfo)
 {
     INIT_API();
     MINIDUMP_NOT_SUPPORTED();
-    ONLY_SUPPORTED_ON_WINDOWS_TARGET();
 
     DWORD_PTR dwStartAddr = NULL;
     BOOL dml = FALSE;
@@ -8961,7 +8939,6 @@ DECLARE_API(GCInfo)
 {
     INIT_API();
     MINIDUMP_NOT_SUPPORTED();
-    ONLY_SUPPORTED_ON_WINDOWS_TARGET();
 
     TADDR taStartAddr = NULL;
     TADDR taGCInfoAddr;
@@ -10204,7 +10181,6 @@ DECLARE_API(DumpGCData)
 
 #ifdef GC_CONFIG_DRIVEN
     MINIDUMP_NOT_SUPPORTED();
-    ONLY_SUPPORTED_ON_WINDOWS_TARGET();
 
     if (!InitializeHeapData ())
     {
@@ -10213,16 +10189,17 @@ DECLARE_API(DumpGCData)
     }
 
     DacpGCInterestingInfoData interestingInfo;
-    interestingInfo.RequestGlobal(g_sos);
-    for (int i = 0; i < DAC_MAX_GLOBAL_GC_MECHANISMS_COUNT; i++)
+    if (!IsServerBuild())
     {
-        ExtOut("%-30s: %d\n", str_gc_global_mechanisms[i], interestingInfo.globalMechanisms[i]);
-    }
+        // Doesn't work (segfaults) for server GCs
+        interestingInfo.RequestGlobal(g_sos);
+        for (int i = 0; i < DAC_MAX_GLOBAL_GC_MECHANISMS_COUNT; i++)
+        {
+            ExtOut("%-30s: %d\n", str_gc_global_mechanisms[i], interestingInfo.globalMechanisms[i]);
+        }
 
-    ExtOut("\n[info per heap]\n");
+        ExtOut("\n[info per heap]\n");
 
-    if (!IsServerBuild())
-    {
         if (interestingInfo.Request(g_sos) != S_OK)
         {
             ExtOut("Error requesting interesting GC info\n");
@@ -10233,6 +10210,8 @@ DECLARE_API(DumpGCData)
     }
     else
     {
+        ExtOut("\n[info per heap]\n");
+
         DWORD dwNHeaps = GetGcHeapCount();
         DWORD dwAllocSize;
         if (!ClrSafeInt<DWORD>::multiply(sizeof(CLRDATA_ADDRESS), dwNHeaps, dwAllocSize))
@@ -10912,7 +10891,6 @@ DECLARE_API(PathTo)
 {
     INIT_API();
     MINIDUMP_NOT_SUPPORTED();
-    ONLY_SUPPORTED_ON_WINDOWS_TARGET();
 
     DWORD_PTR root = NULL;
     DWORD_PTR target = NULL;
@@ -11123,14 +11101,10 @@ DECLARE_API(GCWhere)
     return Status;
 }
 
-#ifndef FEATURE_PAL
-
 DECLARE_API(FindRoots)
 {
-#ifndef FEATURE_PAL
     INIT_API();
     MINIDUMP_NOT_SUPPORTED();
-    ONLY_SUPPORTED_ON_WINDOWS_TARGET();
 
     if (IsDumpFile())
     {
@@ -11189,7 +11163,11 @@ DECLARE_API(FindRoots)
         GcEvtArgs gea = { GC_MARK_END, { ((gen == -1) ? 7 : (1 << gen)) } };
         idp2->SetGcNotification(gea);
         // ... and register the notification handler
+#ifndef FEATURE_PAL
         g_ExtControl->Execute(DEBUG_EXECUTE_NOT_LOGGED, "sxe -c \"!SOSHandleCLRN\" clrn", 0);
+#else
+        g_ExtServices->SetExceptionCallback(HandleExceptionNotification);
+#endif // FEATURE_PAL
         // the above notification is removed in CNotification::OnGcEvent()
     }
     else
@@ -11232,13 +11210,8 @@ DECLARE_API(FindRoots)
     }
 
     return Status;
-#else
-    return E_NOTIMPL;
-#endif
 }
 
-#endif // FEATURE_PAL
-
 class GCHandleStatsForDomains
 {
 public:
@@ -12234,7 +12207,6 @@ DECLARE_API(GCHandleLeaks)
 }
 #endif // FEATURE_PAL
 
-
 class ClrStackImplWithICorDebug
 {
 private:
index ab8f67eb3a69e60154cbdef905cb1948ac779ec1..37b3f73ab4890db7578bf5b6be203d3c5469b914 100644 (file)
@@ -4656,7 +4656,16 @@ OutputVaList(
     int length = _vsnprintf_s((char* const)&g_printBuffer, sizeof(g_printBuffer), _TRUNCATE, format, args);
     if (length > 0)
     {
-        return g_ExtControl->OutputVaList(mask, (char* const)&g_printBuffer, args);
+#ifdef HOST_WINDOWS
+        if (IsInitializedByDbgEng())
+        {
+            return g_ExtControl->Output(mask, "%s", g_printBuffer);
+        }
+        else
+#endif
+        {
+            return g_ExtControl->OutputVaList(mask, (char* const)&g_printBuffer, args);
+        }
     }
     return E_FAIL;
 }
@@ -4671,7 +4680,16 @@ ControlledOutputVaList(
     int length = _vsnprintf_s((char* const)&g_printBuffer, sizeof(g_printBuffer), _TRUNCATE, format, args);
     if (length > 0)
     {
-        return g_ExtControl->ControlledOutputVaList(outputControl, mask, (char* const)&g_printBuffer, args);
+#ifdef HOST_WINDOWS
+        if (IsInitializedByDbgEng())
+        {
+            return g_ExtControl->ControlledOutput(outputControl, mask, "%s", g_printBuffer);
+        }
+        else
+#endif
+        {
+            return g_ExtControl->ControlledOutputVaList(outputControl, mask, (char* const)&g_printBuffer, args);
+        }
     }
     return E_FAIL;
 }
index fcde9cd034c933911ebb05a65029bef1e7b45aeb..b8af171e8067ab6a9fbe5e091641b03a5408f8d6 100644 (file)
@@ -658,9 +658,8 @@ inline void ExtOutIndent()  { WhitespaceOut(Output::g_Indent << 2); }
 
 bool IsDMLEnabled();
 
-
 #ifndef SOS_Assert
-#define SOS_Assert(x)
+#define SOS_Assert _ASSERTE
 #endif
 
 void ConvertToLower(__out_ecount(len) char *buffer, size_t len);
index f487f20d956fe2842c290542ee186e84eebdb0cd..2ed9a26cf1339aa2e000c92a724be6399120beaa 100644 (file)
@@ -156,7 +156,6 @@ sosCommandInitialize(lldb::SBDebugger debugger)
     g_services->AddCommand("clrthreads", new sosCommand("Threads"), "List the managed threads running.");
     g_services->AddCommand("clru", new sosCommand("u"), "Displays an annotated disassembly of a managed method.");
     g_services->AddCommand("dbgout", new sosCommand("dbgout"), "Enable/disable (-off) internal SOS logging.");
-    g_services->AddCommand("logging", new sosCommand("logging"), "Enable/disable internal SOS logging.");
     g_services->AddCommand("dumpalc", new sosCommand("DumpALC"), "Displays details about a collectible AssemblyLoadContext to which the specified object is loaded.");
     g_services->AddCommand("dumparray", new sosCommand("DumpArray"), "Displays details about a managed array.");
     g_services->AddCommand("dumpasync", new sosCommand("DumpAsync"), "Displays information about async \"stacks\" on the garbage-collected heap.");
@@ -164,6 +163,7 @@ sosCommandInitialize(lldb::SBDebugger debugger)
     g_services->AddCommand("dumpclass", new sosCommand("DumpClass"), "Displays information about a EE class structure at the specified address.");
     g_services->AddCommand("dumpdelegate", new sosCommand("DumpDelegate"), "Displays information about a delegate.");
     g_services->AddCommand("dumpdomain", new sosCommand("DumpDomain"), "Displays information all the AppDomains and all assemblies within the domains.");
+    g_services->AddCommand("dumpgcdata", new sosCommand("DumpGCData"), "Displays information about the GC data.");
     g_services->AddCommand("dumpheap", new sosCommand("DumpHeap"), "Displays info about the garbage-collected heap and collection statistics about objects.");
     g_services->AddCommand("dumpil", new sosCommand("DumpIL"), "Displays the Microsoft intermediate language (MSIL) that is associated with a managed method.");
     g_services->AddCommand("dumplog", new sosCommand("DumpLog"), "Writes the contents of an in-memory stress log to the specified file.");
@@ -171,37 +171,52 @@ sosCommandInitialize(lldb::SBDebugger debugger)
     g_services->AddCommand("dumpmodule", new sosCommand("DumpModule"), "Displays information about a EE module structure at the specified address.");
     g_services->AddCommand("dumpmt", new sosCommand("DumpMT"), "Displays information about a method table at the specified address.");
     g_services->AddCommand("dumpobj", new sosCommand("DumpObj"), "Displays info about an object at the specified address.");
-    g_services->AddCommand("dumpvc", new sosCommand("DumpVC"), "Displays info about the fields of a value class.");
+    g_services->AddCommand("dumpruntimetypes", new sosCommand("DumpRuntimeTypes"), "Finds all System.RuntimeType objects in the gc heap and prints the type name and MethodTable they refer too.");
+    g_services->AddCommand("dumpsig", new sosCommand("DumpSig"), "This command dumps the signature of a method or field given by <sigaddr> <moduleaddr>.");
+    g_services->AddCommand("dumpsigelem", new sosCommand("DumpSigElem"), "This command dumps a single element of a signature object.");
     g_services->AddCommand("dumpstack", new sosCommand("DumpStack"), "Displays a native and managed stack trace.");
+    g_services->AddCommand("dumpstackobjects", new sosCommand("DumpStackObjects"), "Displays all managed objects found within the bounds of the current stack.");
     g_services->AddCommand("dso", new sosCommand("DumpStackObjects"), "Displays all managed objects found within the bounds of the current stack.");
+    g_services->AddCommand("dumpvc", new sosCommand("DumpVC"), "Displays info about the fields of a value class.");
     g_services->AddCommand("eeheap", new sosCommand("EEHeap"), "Displays info about process memory consumed by internal runtime data structures.");
     g_services->AddCommand("eestack", new sosCommand("EEStack"), "Runs dumpstack on all threads in the process.");
     g_services->AddCommand("eeversion", new sosCommand("EEVersion"), "Displays information about the runtime version.");
+    g_services->AddCommand("ehinfo", new sosCommand("EHInfo"), "Displays the exception handling blocks in a jitted method.");
     g_services->AddCommand("finalizequeue", new sosCommand("FinalizeQueue"), "Displays all objects registered for finalization.");
+    g_services->AddCommand("findappdomain", new sosCommand("FindAppDomain"), "Attempts to resolve the AppDomain of a GC object.");
+    g_services->AddCommand("findroots", new sosCommand("FindRoots"), "");
     g_services->AddCommand("gchandles", new sosCommand("GCHandles"), "Displays statistics about garbage collector handles in the process.");
+    g_services->AddCommand("gcheapstat", new sosCommand("GCHeapStat"), "Displays statistics about garbage collector.");
+    g_services->AddCommand("gcinfo", new sosCommand("GCInfo"), "Displays info JIT GC encoding for a method.");
     g_services->AddCommand("gcroot", new sosCommand("GCRoot"), "Displays info about references (or roots) to an object at the specified address.");
     g_services->AddCommand("gcwhere", new sosCommand("GCWhere"), "Displays the location in the GC heap of the argument passed in.");
-    g_services->AddCommand("ip2md", new sosCommand("IP2MD"), "Displays the MethodDesc structure at the specified address in code that has been JIT-compiled.");
-    g_services->AddCommand("loadsymbols", new sosCommand("SetSymbolServer", "-loadsymbols"), "Load the .NET Core native module symbols.");
-    g_services->AddCommand("name2ee", new sosCommand("Name2EE"), "Displays the MethodTable structure and EEClass structure for the specified type or method in the specified module.");
-    g_services->AddCommand("pe", new sosCommand("PrintException"), "Displays and formats fields of any object derived from the Exception class at the specified address.");
-    g_services->AddCommand("syncblk", new sosCommand("SyncBlk"), "Displays the SyncBlock holder info.");
     g_services->AddCommand("histclear", new sosCommand("HistClear"), "Releases any resources used by the family of Hist commands.");
     g_services->AddCommand("histinit", new sosCommand("HistInit"), "Initializes the SOS structures from the stress log saved in the debuggee.");
     g_services->AddCommand("histobj", new sosCommand("HistObj"), "Examines all stress log relocation records and displays the chain of garbage collection relocations that may have led to the address passed in as an argument.");
     g_services->AddCommand("histobjfind", new sosCommand("HistObjFind"), "Displays all the log entries that reference an object at the specified address.");
     g_services->AddCommand("histroot", new sosCommand("HistRoot"), "Displays information related to both promotions and relocations of the specified root.");
+    g_services->AddCommand("histstats", new sosCommand("HistStats"), "Displays stress log stats.");
+    g_services->AddCommand("ip2md", new sosCommand("IP2MD"), "Displays the MethodDesc structure at the specified address in code that has been JIT-compiled.");
+    g_services->AddCommand("listnearobj", new sosCommand("ListNearObj"), "displays the object preceeding and succeeding the address passed.");
+    g_services->AddCommand("loadsymbols", new sosCommand("SetSymbolServer", "-loadsymbols"), "Load the .NET Core native module symbols.");
+    g_services->AddCommand("logging", new sosCommand("logging"), "Enable/disable internal SOS logging.");
+    g_services->AddCommand("name2ee", new sosCommand("Name2EE"), "Displays the MethodTable structure and EEClass structure for the specified type or method in the specified module.");
     g_services->AddCommand("objsize", new sosCommand("ObjSize"), "Displays the size of the specified object.");
+    g_services->AddCommand("pe", new sosCommand("PrintException"), "Displays and formats fields of any object derived from the Exception class at the specified address.");
+    g_services->AddCommand("pathto", new sosCommand("PathTo"), "Displays the GC path from <root> to <target>.");
+    g_services->AddCommand("runtimes", new sosCommand("runtimes"), "List the runtimes in the target or change the default runtime.");
+    g_services->AddCommand("stoponcatch", new sosCommand("StopOnCatch"), "Debuggee will break the next time a managed exception is caught during execution");
     g_services->AddCommand("setclrpath", new sosCommand("SetClrPath"), "Set the path to load the runtime DAC/DBI files.");
     g_services->AddCommand("setsymbolserver", new sosCommand("SetSymbolServer"), "Enables the symbol server support ");
     g_services->AddCommand("sympath", new sosCommand("SetSymbolServer", "-sympath"), "Add server, cache and directory paths in the Windows symbol path format.");
     g_services->AddCommand("soshelp", new sosCommand("Help"), "Displays all available commands when no parameter is specified, or displays detailed help information about the specified command. soshelp <command>");
-    g_services->AddCommand("sosstatus", new sosCommand("SOSStatus"), "Displays the global SOS status.");
-    g_services->AddCommand("runtimes", new sosCommand("runtimes"), "List the runtimes in the target or change the default runtime.");
     g_services->AddCommand("sosflush", new sosCommand("SOSFlush"), "Flushes the DAC caches.");
+    g_services->AddCommand("sosstatus", new sosCommand("SOSStatus"), "Displays the global SOS status.");
+    g_services->AddCommand("syncblk", new sosCommand("SyncBlk"), "Displays the SyncBlock holder info.");
     g_services->AddCommand("threadpool", new sosCommand("ThreadPool"), "Displays info about the runtime thread pool.");
     g_services->AddCommand("threadstate", new sosCommand("ThreadState"), "Pretty prints the meaning of a threads state.");
     g_services->AddCommand("token2ee", new sosCommand("token2ee"), "Displays the MethodTable structure and MethodDesc structure for the specified token and module.");
     g_services->AddCommand("verifyheap", new sosCommand("VerifyHeap"), "Checks the GC heap for signs of corruption.");
+    g_services->AddCommand("verifyobj", new sosCommand("VerifyObj"), "Checks the object that is passed as an argument for signs of corruption.");
     return true;
 }
index 0848b3f3fde28a4674f09d46dbfdb275f25037f3..f01d8a5611a4dfb68ead31bdfe97a08f3dae3235 100644 (file)
@@ -103,7 +103,7 @@ public:
         {
             return false;
         }
-        if (PAL_fseek(m_file, (LONG)address, SEEK_SET) != 0)
+        if (PAL_fseek(m_file, (LONG_PTR)address, SEEK_SET) != 0)
         {
             return false;
         }
index 9b461a701a686c6f0b3f71d42e3c2ff8a7cd0e9f..2a9ca3529d40aab60546dac40ee4b412597e7a82 100644 (file)
@@ -161,8 +161,6 @@ public:
         // If it doesn't contain pointers, there isn't a GCDesc
         PTR_MethodTable mt(pMT);
 
-        _ASSERTE(mt->ContainsPointers());
-
         return PTR_CGCDesc(mt);
     }