private MemoryAnalyzer(DataTarget dataTarget)
        {
            // TODO: Exit gracefully for memory dumps from different platforms

            m_dataTarget = dataTarget;
            string dacLocation = m_dataTarget.ClrVersions[0].TryGetDacLocation();
            if (String.IsNullOrEmpty(dacLocation))
                throw new ArgumentException("Cannot find DAC location for process");

            m_runtime = m_dataTarget.CreateRuntime(dacLocation);
            m_heap = m_runtime.GetHeap();
        }
示例#2
0
        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 ClrHeapDecorator(ClrRuntime clrRuntime, ThreadDispatcher threadDispatcher)
		{
			_threadDispatcher = threadDispatcher;
			_clrHeap = threadDispatcher.Process(() => clrRuntime.GetHeap());

			

			_threadDispatcher.Process(()=>
			{
				objectIndex = IndexBuilder.Build(_clrHeap);
				GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
			});
		}
		private static IEnumerable<TypeHeapStat> GetHeapStatsByTypeForObjectSet(ClrRuntime clrRuntime, IEnumerable<ulong> objectIdSet)
		{
			ClrHeap heap = clrRuntime.GetHeap();

			return from oid in objectIdSet
				   let ot = heap.GetObjectType(oid)
				   group oid by ot into objectTypeGroup
				   let otSize = objectTypeGroup.Sum(oid => (uint)objectTypeGroup.Key.GetSize(oid))
				   select new TypeHeapStat
				   {
					   TypeName = objectTypeGroup.Key.Name,
					   TotalHeapSize = otSize,
					   NumberOfInstances = objectTypeGroup.Count()
				   };
		}
示例#5
0
        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, "  ClrVersion{0}: {1}", dataTarget.ClrVersions.Count > 1 ? "s" : "", string.Join(", ", dataTarget.ClrVersions));
            logger?.WriteLine(LogKind.Info, "  Architecture: " + dataTarget.Architecture);
            logger?.WriteLine(LogKind.Info, "  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,
                                  "  {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, "  TotalHeapSize: {0:N0} bytes ({1:N2} MB)", heap.TotalHeapSize, heap.TotalHeapSize / 1024.0 / 1024.0);
            logger?.WriteLine(LogKind.Info, "  Gen0: {0,10:N0} bytes", heap.GetSizeByGen(0));
            logger?.WriteLine(LogKind.Info, "  Gen1: {0,10:N0} bytes", heap.GetSizeByGen(1));
            logger?.WriteLine(LogKind.Info, "  Gen2: {0,10:N0} bytes", heap.GetSizeByGen(2));
            logger?.WriteLine(LogKind.Info, "   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,
                                  "    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();
        }
示例#6
0
    public static void PrintDict(ClrRuntime runtime, string args)
    {
        bool failed = false;
        ulong obj = 0;
        try
        {
            obj = Convert.ToUInt64(args, 16);
            failed = obj == 0;
        }
        catch (ArgumentException)
        {
            failed = true;
        }

        if (failed)
        {
            Console.WriteLine("Usage: !PrintDict <dictionary>");
            return;
        }

        ClrHeap heap = runtime.GetHeap();
        ClrType type = heap.GetObjectType(obj);

        if (type == null)
        {
            Console.WriteLine("Invalid object {0:X}", obj);
            return;
        }

        if (!type.Name.StartsWith("System.Collections.Generic.Dictionary"))
        {
            Console.WriteLine("Error: Expected object {0:X} to be a dictionary, instead it's of type '{1}'.");
            return;
        }

        // Get the entries field.
        ulong entries = type.GetFieldValue(obj, "entries");

        if (entries == 0)
            return;

        ClrType entryArray = heap.GetObjectType(entries);
        ClrType arrayComponent = entryArray.ArrayComponentType;
        ClrInstanceField hashCodeField = arrayComponent.GetFieldByName("hashCode");
        ClrInstanceField keyField = arrayComponent.GetFieldByName("key");
        ClrInstanceField valueField = arrayComponent.GetFieldByName("value");

        Console.WriteLine("{0,8} {1,16} : {2}", "hash", "key", "value");
        int len = entryArray.GetArrayLength(entries);
        for (int i = 0; i < len; ++i)
        {
            ulong arrayElementAddr = entryArray.GetArrayElementAddress(entries, i);

            int hashCode = (int)hashCodeField.GetFieldValue(arrayElementAddr, true);
            object key = keyField.GetFieldValue(arrayElementAddr, true);
            object value = valueField.GetFieldValue(arrayElementAddr, true);

            key = Format(heap, key);
            value = Format(heap, value);

            bool skip = key is ulong && (ulong)key == 0 && value is ulong && (ulong)value == 0;

            if (!skip)
                Console.WriteLine("{0,8:X} {1,16} : {2}", hashCode, key, value);
        }
    }
示例#7
0
        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);
        }
示例#8
0
 private void CreateRuntime(int clrVersionIndex, string dacLocation)
 {
     _runtime = _target.ClrVersions[clrVersionIndex].CreateRuntime(dacLocation);
     _heap = _runtime.GetHeap();
 }