public static ClrType GetTypeFromEE(ClrRuntime Runtime, ulong EEClass) { ClrHeap heap = Runtime.GetHeap(); ClrType type = null; int max = heap.TypeIndexLimit; if (max < 1) { var objList = heap.EnumerateObjects().GetEnumerator(); if (objList.MoveNext()) { type = heap.GetObjectType(objList.Current); } } else { type = Runtime.GetHeap().GetTypeByIndex(0); } if (type == null) { throw new NullReferenceException("There is no object in the heap"); } ClrType EEType = (ClrType)RunMethod(type, "ConstructObjectType", EEClass); return(EEType); }
public StaticField(ClrRuntime runtime, string typee, string name) { Domain = runtime.AppDomains.First(); ClrHeap heap = runtime.GetHeap(); ClrType type = heap.GetTypeByName(typee); Field = type.GetStaticFieldByName(name); Heap = runtime.GetHeap(); }
private void DumpHandles(int GroupOnly = 0, string filterByType = null, string filterByObjType = null) { Dictionary <string, int> categories = new Dictionary <string, int>(); if (m_runtime.PointerSize == 8) { WriteLine("Handle Object Refs Type Object Type"); } else { WriteLine("Handle Object Refs Type Object Type"); } int i = 0; int c = 0; foreach (var handle in m_runtime.EnumerateHandles()) { if (!categories.ContainsKey(handle.HandleType.ToString())) { categories[handle.HandleType.ToString()] = 0; } categories[handle.HandleType.ToString()]++; ClrType obj = m_runtime.GetHeap().GetObjectType(handle.Object); if ( (String.IsNullOrEmpty(filterByType) || handle.HandleType.ToString().ToLowerInvariant().Contains(filterByType.ToLowerInvariant())) && (String.IsNullOrEmpty(filterByObjType) || obj.Name.ToLowerInvariant().Contains(filterByObjType.ToLowerInvariant())) ) { if (GroupOnly == 0) { Write("{0:%p} {1:%p}", handle.Address, handle.Object); Write(" {0,4} {1,-15}", handle.RefCount, handle.HandleType); Write(" {0}", obj.Name); WriteLine(""); } c++; } i++; } WriteLine(""); WriteLine("{0,8:#,#} Objects Listed or met the criteria", c); if (c != i) { WriteLine("{0,8:#,#} Objects Skipped by the filter(s)", i - c); } WriteLine(""); WriteLine("{0,8:#,#} Handle(s) found in {1} categories", i, categories.Keys.Count); foreach (var cat in categories.Keys) { Write("{0,8:#,#} ", categories[cat]); Write("<link cmd=\"!wcghandle -handletype {0}\">{0}</link>", cat); WriteLine(" found"); } WriteLine(""); }
public IEnumerable <ClrObject> EnumerateObjectsFromSource([NotNull] ClrRuntime runtime) { var threads = runtime.Threads; var heap = runtime.GetHeap(); var hashSet = new HashSet <ulong>(); foreach (var thread in threads) { if (this.ThreadFilterHelper.ShouldSkip(thread)) { continue; } foreach (var obj in thread.EnumerateStackObjects(includePossiblyDead: true)) { var type = heap.GetObjectType(obj.Object); if (type == null) { continue; } if (hashSet.Add(obj.Object)) { yield return(new ClrObject(obj.Object, type)); } } } }
private static void DumpHeapByType(ClrRuntime runtime, string typeName, IWriter outWriter) { int count = 0; ClrHeap heap = runtime.GetHeap(); foreach (ClrSegment seg in heap.Segments) { for (ulong obj = seg.FirstObject; obj != 0; obj = seg.NextObject(obj)) { ClrType type = heap.GetObjectType(obj); // If heap corruption, continue past this object. if (type == null) { continue; } if (string.Equals(type.Name, typeName, StringComparison.InvariantCultureIgnoreCase)) { count++; ulong size = type.GetSize(obj); outWriter.WriteLine($"{obj,12:X} {size,8:n0} {seg.GetGeneration(obj),1:n0} {type.Name}"); } } } outWriter.WriteLine($"Total {count} objects"); }
public ClrHeap GetHeap(DataTarget target) { var clrVersion = target.ClrVersions.FirstOrDefault(); if (clrVersion == null) { return(null); } ClrRuntime runtime = null; try { runtime = clrVersion.CreateRuntime(); return(runtime.GetHeap()); } catch (Exception ex) { DebugPrinter.Write("Got from CreateRuntime or GetHeap: {0}", ex); // If it is a target architecture mismatch hide error message and start x64 to try again later. if (Environment.Is64BitProcess) { Console.WriteLine("Error: Is the dump file opened by another process (debugger)? If yes close the debugger first."); Console.WriteLine(" If the dump comes from a different computer with another CLR version {0} that you are running on your machine you need to download the matching mscordacwks.dll first. Check out " + DacCollection + " and download the matching version/s.", clrVersion.Version); Console.WriteLine(" Then set _NT_SYMBOL_PATH=PathToYourDownloadedMscordackwks.dll e.g. _NT_SYMBOL_PATH=c:\\temp\\mscordacwks in the shell where you did execute MemAnalyzer and then try again."); Console.WriteLine(); } throw; } }
private static Dictionary <ClrType, Entry> ReadHeap(string dump, string dac) { // Load one crash dump and build heap statistics. ClrRuntime runtime = CreateRuntime(dump, dac); ClrHeap heap = runtime.GetHeap(); var entries = new Dictionary <ClrType, Entry>(); foreach (var seg in heap.Segments) { for (ulong obj = seg.FirstObject; obj != 0; obj = seg.NextObject(obj)) { ClrType type = heap.GetObjectType(obj); if (type == null) { continue; } Entry entry; if (!entries.TryGetValue(type, out entry)) { entry = new Entry(); entry.Type = type; entries[type] = entry; } entry.Count++; entry.Size += (long)type.GetSize(obj); } } return(entries); }
private void TouchOtherRegions(DumpReaderLogger readerLogger, ClrRuntime runtime) { // Touch all threads, stacks, frames foreach (var t in runtime.Threads) { foreach (var f in t.StackTrace) { try { var ip = f.InstructionPointer; } catch (Exception) { } } } // Touch all modules runtime.Modules.Count(); // Touch all heap regions, roots, types var heap = runtime.GetHeap(); heap.EnumerateRoots(enumerateStatics: false).Count(); heap.EnumerateTypes().Count(); // TODO Check if it's faster to construct sorted inside ReaderWrapper foreach (var kvp in readerLogger.Ranges) { _otherClrRegions.Add(kvp.Key, kvp.Value); } }
private static Dictionary <ClrType, HeapStatsEntry> HeapDump(ClrRuntime runtime) { Dictionary <ClrType, HeapStatsEntry> stats = new Dictionary <ClrType, HeapStatsEntry>(); ClrHeap heap = runtime.GetHeap(); foreach (ClrSegment seg in heap.Segments) { for (ulong obj = seg.FirstObject; obj != 0; obj = seg.NextObject(obj)) { ClrType type = heap.GetObjectType(obj); if (type == null) { continue; } HeapStatsEntry entry; if (!stats.TryGetValue(type, out entry)) { entry = new HeapStatsEntry { Name = type.Name }; stats[type] = entry; } entry.Count++; entry.Size += type.GetSize(obj); } } return(stats); }
private void EnsureInitialized([NotNull] ClrRuntime runtime) { if (initialized) { return; } try { ClrHeap heap = runtime.GetHeap(); enumeratedTypes = new List <ClrType>(); foreach (string typename in EnumeratedTypesNames) { if (string.IsNullOrEmpty(typename)) { continue; } ClrType tmp = heap.GetTypeByName(typename); if (tmp == null) { Trace.TraceWarning("{0} type was not found in runtime.", typename); continue; } enumeratedTypes.Add(tmp); } } finally { initialized = true; } }
public void ArrayReferenceEnumeration() { using (DataTarget dt = TestTargets.Types.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.GetHeap(); ClrAppDomain domain = runtime.AppDomains.Single(); ClrModule typesModule = runtime.GetModule("types.exe"); ClrType type = heap.GetTypeByName("Types"); ulong s_array = (ulong)type.GetStaticFieldByName("s_array").GetValue(domain); ulong s_one = (ulong)type.GetStaticFieldByName("s_one").GetValue(domain); ulong s_two = (ulong)type.GetStaticFieldByName("s_two").GetValue(domain); ulong s_three = (ulong)type.GetStaticFieldByName("s_three").GetValue(domain); ClrType arrayType = heap.GetObjectType(s_array); List <ulong> objs = new List <ulong>(); arrayType.EnumerateRefsOfObject(s_array, (obj, offs) => objs.Add(obj)); // We do not guarantee the order in which these are enumerated. Assert.AreEqual(3, objs.Count); Assert.IsTrue(objs.Contains(s_one)); Assert.IsTrue(objs.Contains(s_two)); Assert.IsTrue(objs.Contains(s_three)); } }
public void ComponentType() { // Simply test that we can enumerate the heap. using (DataTarget dt = TestTargets.Types.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.GetHeap(); foreach (ulong obj in heap.EnumerateObjectAddresses()) { var type = heap.GetObjectType(obj); Assert.IsNotNull(type); if (type.IsArray || type.IsPointer) { Assert.IsNotNull(type.ComponentType); } else { Assert.IsNull(type.ComponentType); } } } }
public void ArrayComponentTypeTest() { using (DataTarget dt = TestTargets.AppDomains.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.GetHeap(); // Ensure that we always have a component for every array type. foreach (ulong obj in heap.EnumerateObjectAddresses()) { ClrType type = heap.GetObjectType(obj); Assert.IsTrue(!type.IsArray || type.ComponentType != null); foreach (var field in type.Fields) { Assert.IsNotNull(field.Type); Assert.IsTrue(!field.Type.IsArray || field.Type.ComponentType != null); Assert.AreSame(heap, field.Type.Heap); } } foreach (ClrModule module in runtime.Modules) { foreach (ClrType type in module.EnumerateTypes()) { Assert.IsTrue(!type.IsArray || type.ComponentType != null); Assert.AreSame(heap, type.Heap); } } } }
public void ArrayOffsetsTest() { using (DataTarget dt = TestTargets.Types.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.GetHeap(); ClrAppDomain domain = runtime.AppDomains.Single(); ClrModule typesModule = runtime.GetModule("types.exe"); ClrType type = heap.GetTypeByName("Types"); ulong s_array = (ulong)type.GetStaticFieldByName("s_array").GetValue(domain); ulong s_one = (ulong)type.GetStaticFieldByName("s_one").GetValue(domain); ulong s_two = (ulong)type.GetStaticFieldByName("s_two").GetValue(domain); ulong s_three = (ulong)type.GetStaticFieldByName("s_three").GetValue(domain); ulong[] expected = new ulong[] { s_one, s_two, s_three }; ClrType arrayType = heap.GetObjectType(s_array); for (int i = 0; i < expected.Length; i++) { Assert.AreEqual(expected[i], (ulong)arrayType.GetArrayElementValue(s_array, i)); ulong address = arrayType.GetArrayElementAddress(s_array, i); ulong value = dt.DataReader.ReadPointerUnsafe(address); Assert.IsNotNull(address); Assert.AreEqual(expected[i], value); } } }
public void MethodTableHeapEnumeration() { using (DataTarget dt = TestTargets.Types.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.GetHeap(); foreach (ClrType type in heap.EnumerateObjectAddresses().Select(obj => heap.GetObjectType(obj)).Unique()) { Assert.AreNotEqual(0ul, type.MethodTable); ClrType typeFromHeap; if (type.IsArray) { ClrType componentType = type.ComponentType; Assert.IsNotNull(componentType); typeFromHeap = heap.GetTypeByMethodTable(type.MethodTable, componentType.MethodTable); } else { typeFromHeap = heap.GetTypeByMethodTable(type.MethodTable); } Assert.AreEqual(type.MethodTable, typeFromHeap.MethodTable); Assert.AreSame(type, typeFromHeap); } } }
public void TypeEqualityTest() { // This test ensures that only one ClrType is created when we have a type loaded into two different AppDomains with two different // method tables. const string TypeName = "Foo"; using (DataTarget dt = TestTargets.AppDomains.LoadFullDump()) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.GetHeap(); ClrType[] types = (from obj in heap.EnumerateObjectAddresses() let t = heap.GetObjectType(obj) where t.Name == TypeName select t).ToArray(); Assert.AreEqual(2, types.Length); Assert.AreEqual(types[0], types[1]); ClrModule module = runtime.Modules.Where(m => Path.GetFileName(m.FileName).Equals("sharedlibrary.dll", StringComparison.OrdinalIgnoreCase)).Single(); ClrType typeFromModule = module.GetTypeByName(TypeName); Assert.AreEqual(TypeName, typeFromModule.Name); Assert.AreEqual(types[0], typeFromModule); } }
public Boolean RefreshHeap(Int32 ProcessId) { // Clear all variables on a heap read this.Heap = null; this.Roots = new Dictionary <UInt64, ClrRoot>(); this.Fields = new Dictionary <UInt64, ClrField>(); try { DataTarget dataTarget = DataTarget.AttachToProcess(ProcessId, AttachTimeout, AttachFlag.Passive); if (dataTarget.ClrVersions.Count <= 0) { return(false); } ClrInfo version = dataTarget.ClrVersions[0]; ClrRuntime runtime = version.CreateRuntime(); this.Heap = runtime.GetHeap(); } catch { } return(this.Heap == null ? false : true); }
public virtual IEnumerable <ClrObject> EnumerateObjectsFromSource([NotNull] ClrRuntime runtime) { Assert.ArgumentNotNull(runtime, "runtime"); ClrHeap heap = runtime.GetHeap(); Assert.IsNotNull(heap, "heap"); #if LimitEnumerator var limit = 10000; var current = 0; #endif foreach (ulong objAddress in heap.EnumerateObjectAddresses()) { var tp = heap.GetObjectType(objAddress); if (tp == null) { continue; } #if LimitEnumerator ++current; if (current > limit) { yield break; } #endif yield return(new ClrObject(objAddress, tp)); } }
// read the heap and construct a list of entries per CLR type private static Dictionary <ClrType, Entry> ReadHeap(ClrRuntime runtime) { ClrHeap heap = runtime.GetHeap(); var entries = new Dictionary <ClrType, Entry>(); foreach (var seg in heap.Segments) { for (ulong obj = seg.FirstObject; obj != 0; obj = seg.NextObject(obj)) { ClrType type = heap.GetObjectType(obj); if (type == null) { continue; } Entry entry; if (!entries.TryGetValue(type, out entry)) { entry = new Entry(); entry.Type = type; entries.Add(type, entry); } entry.Count++; entry.Size += (long)type.GetSize(obj); } } return(entries); }
private ulong GetClrHeapSizeByGeneration(Tuple <int, int> input) { int runtimeId = input.Item1; int generation = input.Item2; ClrRuntime clrRuntime = runtimesCache[runtimeId]; return(clrRuntime.GetHeap().GetSizeByGen(generation)); }
static void Main(string[] args) { ulong obj; string dump, dac; if (!TryParseArgs(args, out obj, out dump, out dac)) { Usage(); Environment.Exit(1); } try { // Create a ClrRuntime instance from the dump and dac location. The ClrRuntime // object represents a version of CLR loaded in the process. It contains data // such as the managed threads in the process, the AppDomains in the process, // the managed heap, and so on. ClrRuntime runtime = CreateRuntime(dump, dac); // To check whether obj is actually a valid object, we attempt to get its type. // If the type is null then we do not have a valid object. ClrHeap heap = runtime.GetHeap(); ClrType type = heap.GetObjectType(obj); if (type == null) { Console.WriteLine("{0:X} is not a valid object.", obj); return; } // Set up initial state. m_considered = new ObjectSet(heap); m_targets[obj] = new Node(obj, type); // Enumerating all roots in the process takes a while. We do it once and full this list. // (Note we actually also get static variables as roots instead of simply pinned object // arrays.) List <ClrRoot> roots = FillRootDictionary(heap); foreach (var root in roots) { if (m_completedRoots.Contains(root) || m_considered.Contains(root.Object)) { continue; } Node path = FindPathToTarget(heap, root); if (path != null) { PrintOnePath(path); } } } catch (Exception ex) { Console.WriteLine("Unhandled exception:"); Console.WriteLine(ex); } }
private Tuple <int, Tuple <ulong, int>[]> EnumerateClrHeapObjects(Tuple <int, int> input) { int runtimeId = input.Item1; int batchCount = input.Item2; ClrRuntime clrRuntime = runtimesCache[runtimeId]; ClrHeap clrHeap = clrRuntime.GetHeap(); return(EnumerateVariables(EnumerateClrHeapObjects(clrHeap), batchCount)); }
private int GetClrHeapObjectType(Tuple <int, ulong> input) { int runtimeId = input.Item1; ulong address = input.Item2; ClrRuntime clrRuntime = runtimesCache[runtimeId]; ClrType clrType = clrRuntime.GetHeap().GetObjectType(address); return(GetClrTypeId(clrType)); }
public static IEnumerable <TypeStat> GetTypesOnHeap(this ClrRuntime clr, string startsWith = "") { var heap = clr.GetHeap(); //http://blogs.msdn.com/b/dotnet/archive/2013/05/01/net-crash-dump-and-live-process-inspection.aspx var result = from obj in clr.GetHeap().EnumerateObjects() let type = heap.GetObjectType(obj) where type.Name.StartsWith(startsWith) group obj by type into g let size = g.Sum(obj => (uint)g.Key.GetSize(obj)) orderby size descending select new TypeStat() { Name = g.Key.Name, Count = g.Count(), Size = size, }; return(result); }
protected virtual bool IsOldSitecore(ClrRuntime runtime) { var heap = runtime.GetHeap(); var factoryType = heap.GetTypeByName(typeof(Configuration.Factory).FullName); // Config was moved to a new class in 8.2 at same time with DI. var diPlaceholder = factoryType.GetStaticFieldByName("Instance"); return(diPlaceholder == null); }
public static int EntryPoint(string pwzArgument) { Debug.WriteLine("[KeeFarceDLL] Starting"); //string processName = Process.GetCurrentProcess().ProcessName; //MessageBox.Show("The current process is " + processName + " and I am running C# code! Yuss!"); if (is64Bit) { Debug.WriteLine("[KeeFarceDLL] Target is 64 bit"); } // Retrieve the DocumentManagerEx object off the heap // TODO: KeePass can support multiple password files , so should probably modify this to load // ALL of the DocumentManagerEx's into a list and process 'em, as opposed to just breaking // after finding the first one. IntPtr docManagerPtr = IntPtr.Zero; using (DataTarget dataTarget = DataTarget.AttachToProcess(Process.GetCurrentProcess().Id, 5000, AttachFlag.Passive)) { string dacLocation = dataTarget.ClrVersions[0].TryGetDacLocation(); ClrRuntime runtime = CreateRuntimeHack(dataTarget, dacLocation, 4, 5); Debug.WriteLine("[KeeFarceDLL] Attached to process."); ClrHeap heap = runtime.GetHeap(); foreach (ulong obj in heap.EnumerateObjects()) { ClrType type = heap.GetObjectType(obj); ulong size = type.GetSize(obj); if (type.Name == "KeePass.UI.DocumentManagerEx") { Debug.WriteLine("[KeeFarceDLL] Found DocumentManagerEx at: " + obj.ToString("X") + " " + type.Name); docManagerPtr = (IntPtr)obj; break; } } if (docManagerPtr == IntPtr.Zero) { // Didn't find a document manager, time to return. Debug.WriteLine("[KeeFarceDLL] No DocumentManagerEx found"); return(1); } } // Get the DocumentManagerEx object Converter <object> ptrconv = new Converter <object>(); object documentManagerEx = ptrconv.ConvertFromIntPtr(docManagerPtr); var info = new DocumentManagerExInfo(documentManagerEx); int r = doExport(info.ActiveDatabase, info.RootGroup, exportFile); return(r); }
public ClrMDSession(DataTarget target, ClrRuntime runtime) { ClrMDSession.Detach(); Target = target; Runtime = runtime; Heap = Runtime.GetHeap(); m_allObjects = new Lazy <List <ClrObject> >(() => Heap.EnumerateClrObjects().ToList()); s_currentSession = this; }
public void WorkstationSegmentTests() { using (DataTarget dt = TestTargets.Types.LoadFullDump(GCMode.Workstation)) { ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrHeap heap = runtime.GetHeap(); Assert.IsFalse(runtime.ServerGC); CheckSegments(heap); } }
private void PrintRuntimeDiagnosticInfo(DataTarget dataTarget, ClrRuntime runtime) { logger?.WriteLine(LogKind.Header, "\nRuntime Diagnostic Information"); logger?.WriteLine(LogKind.Header, "------------------------------"); logger?.WriteLine(LogKind.Header, "\nDataTarget Info:"); logger?.WriteLine(LogKind.Info, string.Format(" ClrVersion{0}: {1}", dataTarget.ClrVersions.Count > 1 ? "s" : "", string.Join(", ", dataTarget.ClrVersions))); logger?.WriteLine(LogKind.Info, " Architecture: " + dataTarget.Architecture); logger?.WriteLine(LogKind.Info, string.Format(" PointerSize: {0} ({1}-bit)", dataTarget.PointerSize, dataTarget.PointerSize == 8 ? 64 : 32)); logger?.WriteLine(LogKind.Info, " SymbolPath: " + dataTarget.GetSymbolPath()); logger?.WriteLine(LogKind.Header, "\nClrRuntime Info:"); logger?.WriteLine(LogKind.Info, " ServerGC: " + runtime.ServerGC); logger?.WriteLine(LogKind.Info, " HeapCount: " + runtime.HeapCount); logger?.WriteLine(LogKind.Info, " Thread Count: " + runtime.Threads.Count); logger?.WriteLine(LogKind.Header, "\nClrRuntime Modules:"); foreach (var module in runtime.EnumerateModules()) { logger?.WriteLine(LogKind.Info, string.Format( " {0,36} Id:{1} - {2,10:N0} bytes @ 0x{3:X16}", Path.GetFileName(module.FileName), module.AssemblyId.ToString().PadRight(10), module.Size, module.ImageBase)); } ClrHeap heap = runtime.GetHeap(); logger?.WriteLine(LogKind.Header, "\nClrHeap Info:"); logger?.WriteLine(LogKind.Info, string.Format(" TotalHeapSize: {0:N0} bytes ({1:N2} MB)", heap.TotalHeapSize, heap.TotalHeapSize / 1024.0 / 1024.0)); logger?.WriteLine(LogKind.Info, string.Format(" Gen0: {0,10:N0} bytes", heap.GetSizeByGen(0))); logger?.WriteLine(LogKind.Info, string.Format(" Gen1: {0,10:N0} bytes", heap.GetSizeByGen(1))); logger?.WriteLine(LogKind.Info, string.Format(" Gen2: {0,10:N0} bytes", heap.GetSizeByGen(2))); logger?.WriteLine(LogKind.Info, string.Format(" LOH: {0,10:N0} bytes", heap.GetSizeByGen(3))); logger?.WriteLine(LogKind.Info, " Segments: " + heap.Segments.Count); foreach (var segment in heap.Segments) { logger?.WriteLine(LogKind.Info, string.Format(" Segment: {0,10:N0} bytes, {1,10}, Gen0: {2,10:N0} bytes, Gen1: {3,10:N0} bytes, Gen2: {4,10:N0} bytes", segment.Length, segment.IsLarge ? "Large" : (segment.IsEphemeral ? "Ephemeral" : "Unknown"), segment.Gen0Length, segment.Gen1Length, segment.Gen2Length)); } logger?.WriteLine(); }
private void StartRuntime(string Target) { DataTarget dataTarget = DataTarget.LoadCrashDump(Target); ClrInfo latest = null; foreach (var version in dataTarget.ClrVersions) { WriteLine("Version: {0}.{1}.{2}.{3} from {4}", version.Version.Major, version.Version.Minor, version.Version.Patch, version.Version.Revision, version.DacInfo.FileName); latest = version; } m_runtime = dataTarget.CreateRuntime(latest.TryDownloadDac()); ulong strMT, arrMT, freeMT = 0; AdHoc.GetCommonMT(m_runtime, out strMT, out arrMT, out freeMT); WriteLine("Free MT: {0:x16}, String MT: {1:x16}, Array MT: {2:x16}", freeMT, strMT, arrMT); WriteLine("== App Domains ==="); int i = 0; DumpDomains(); //foreach (var appDomain in AdHoc.GetDomains(m_runtime)) //{ // i++; // if (i == 1) // { // WriteLine("{0:x16} System", appDomain.Address); // WriteLine(" Modules: {0}", appDomain.Modules.Count); // continue; // } // if (i == 2) // { // WriteLine("{0:x16} Shared", appDomain.Address); // WriteLine(" Modules: {0}", appDomain.Modules.Count); // continue; // } // WriteLine("{0:x16} {1}", appDomain.Address, appDomain.Name); // WriteLine(" {0}{1}", appDomain.ApplicationBase, appDomain.ConfigurationFile); // WriteLine(" Modules: {0}", appDomain.Modules.Count); //} WriteLine("=================="); WriteLine("Heap(s): {0} GC Server Mode: {1}", m_runtime.HeapCount, m_runtime.ServerGC); m_heap = m_runtime.GetHeap(); heapObjs = m_heap.EnumerateObjects().GetEnumerator(); count = 0; }