private static DacInfo ReadProperties(string dacName) { if (string.IsNullOrEmpty(dacName)) { return(null); } lock (_dacMap.SyncRoot) { var res = _dacMap[dacName] as DacInfo; if (res == null) { PXFieldState[] fieldStates = null; var dac = BuildManager.GetType(dacName, false); if (dac != null) { var graph = new PXGraph(); fieldStates = PXFieldState.GetFields(graph, new Type[] { dac }, false); } res = DacInfo.Create(dacName, fieldStates); _dacMap.Add(dacName, res); } return(res); } }
public static DacInfo Create(string name, params PXFieldState[] fieldStates) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } var properties = new List <FieldInfo>(); if (fieldStates != null) { foreach (var state in fieldStates) { if (state.Visibility != PXUIVisibility.Invisible && !string.IsNullOrEmpty(state.DisplayName)) { properties.Add(new FieldInfo(state.Name, state.DisplayName, state.DataType, state.ViewName)); } } } properties.Sort((info, fieldInfo) => StringComparer.OrdinalIgnoreCase.Compare(info.Name, fieldInfo.Name)); var res = new DacInfo(name); foreach (FieldInfo field in properties) { res._map.Add(field.Name, field); } return(res); }
/// <summary> /// Initializes a new instance of the <see cref="DacInfoAdapter" /> class. /// </summary> /// <param name="converter">The converter.</param> /// <param name="dacInfo">The dac information.</param> /// <exception cref="ArgumentNullException">dacInfo</exception> /// <inheritdoc /> public DacInfoAdapter(IConverter converter, DacInfo dacInfo) : base(converter) { DacInfo = dacInfo ?? throw new ArgumentNullException(nameof(dacInfo)); FileName = DacInfo.FileName; FileSize = DacInfo.FileSize; ImageBase = DacInfo.ImageBase; IsManaged = DacInfo.IsManaged; IsRuntime = DacInfo.IsRuntime; TimeStamp = DacInfo.TimeStamp; }
/// <summary> /// Prints out CLR Summary information /// </summary> public void ClrDacInfo() { if (DataTargetInstance == null) { return; } // ClrMD DataTarget instance from dbgeng Console.WriteLine(">>> CLR Info"); Console.WriteLine($"Architecture.: {DataTargetInstance.DataReader.Architecture}"); Console.WriteLine($"Pointer Size.: {DataTargetInstance.DataReader.PointerSize}"); Console.WriteLine($"Display Name.: {DataTargetInstance.DataReader.DisplayName}"); foreach (ClrInfo clr in DataTargetInstance.ClrVersions) { Console.WriteLine($"Clr Flavor...: {clr.Flavor}"); Console.WriteLine($"Clr Version..: {clr.Version}"); // This is the data needed to request the dac from the symbol server: DacInfo dacInfo = clr.DacInfo; Console.WriteLine("Filesize.....: {0:X}", dacInfo.IndexFileSize); Console.WriteLine("Timestamp....: {0:X}", dacInfo.IndexTimeStamp); Console.WriteLine("Dac File.....: {0}", dacInfo.PlatformSpecificFileName); // If we just happen to have the correct dac file installed on the machine, // the "LocalMatchingDac" property will return its location on disk: string dacLocation = clr.DacInfo.LocalDacPath; if (!string.IsNullOrEmpty(dacLocation)) { Console.WriteLine("Local DAC....: " + dacLocation); } } Console.WriteLine(); #region >>> Sample output of above code //>>> CLR Info //Architecture.: Amd64 //Pointer Size.: 8 //Display Name.: DbgEng, IDebugClient = 1a4fe703148 // Clr Flavor...: Core // Clr Version..: 4.700.20.20201 //Filesize.....: 56C000 //Timestamp....: 5E867108 //Dac File.....: mscordaccore_Amd64_Amd64_4.700.20.20201.dll //Local DAC....: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\mscordaccore.dll #endregion }
protected void CreateRuntime() { //We will only be using the first CLRVerion we find. SxS is not something that we will be supporting right now. Version = Target.ClrVersions[0]; DacInfo dac = Version.DacInfo; if (dac == null) { PrintDebugMessage("Cannot obtain the dac from the dump. Consider getting the DAC from the machine where the dumps were collected."); throw new ClrDiagnosticsException("Failed to get DAC."); } Runtime = Version.CreateRuntime(); if (Runtime == null) { PrintDebugMessage("Creation of the runtime failed."); //TODO: Add a method to try an get the DAC from the user. This will need a new entry point. Likely override the constructor. throw new ClrDiagnosticsException("Failed to create CLR runtime."); } }
private DiagnosticAnalyzer(DataTarget dataTarget, bool cacheObjects) { _dataTarget = dataTarget; CacheAllObjects = cacheObjects; //_dataTarget.BinaryLocator.FindBinary() if (_dataTarget.ClrVersions.Length == 0) { throw new Exception("No compatible CLR has been found on this machine"); } if (_dataTarget.ClrVersions.Length > 1) { Debug.WriteLine("Multiple compatible CLR have been found on this machine, picking the first of the following list"); foreach (var version in _dataTarget.ClrVersions) { var dacFilename = version.DacInfo.PlatformSpecificFileName; var moduleInfo = version.ModuleInfo; Debug.WriteLine("CLR Version: " + version.Version); Debug.WriteLine("Filesize: {0:X}", moduleInfo.IndexFileSize); Debug.WriteLine("Timestamp: {0:X}", moduleInfo.IndexTimeStamp); Debug.WriteLine("Dac File: {0}", dacFilename); Debug.WriteLine(""); } } _clrInfo = _dataTarget.ClrVersions[0]; if (_clrInfo.DacInfo.LocalDacPath == null) { throw new Exception($"The runtime used in the dump is {_clrInfo.DacInfo.Version} and cannot be found on this installation"); } _clrLocation = new FileInfo(_clrInfo.DacInfo.LocalDacPath); _clrRuntime = _clrInfo.CreateRuntime(); _dacInfo = _clrInfo.DacInfo; PrepareGCRootCache(); }
/// <summary> /// Attempts to locate a dac via the symbol server. This function will then copy the file /// locally to the symbol cache and return the location of the local file on disk. Note that /// the dac should not validate if the properties of the file match the one it was indexed under. /// </summary> /// <param name="dac">The dac to locate.</param> /// <returns>A full path on disk (local) of where the binary was copied to, null if it was not found.</returns> public async Task <string> FindBinaryAsync(DacInfo dac) { return(await FindBinaryAsync(dac, false)); }
public string DownloadBinary(DacInfo dac) { return(DownloadBinary(dac, false)); }
/// <summary> /// Attempts to locate a dac via the symbol server. This function will then copy the file /// locally to the symbol cache and return the location of the local file on disk. Note that /// the dac should not validate if the properties of the file match the one it was indexed under. /// </summary> /// <param name="dac">The dac to locate.</param> /// <returns>A full path on disk (local) of where the binary was copied to, null if it was not found.</returns> public string FindBinary(DacInfo dac) { return(FindBinary(dac, false)); }
static void Main(string[] args) { Console.WriteLine("Hello World!"); var crashDumpPath = "../../artefacts/core_20200503_003216"; using (DataTarget dataTarget = DataTarget.LoadDump(crashDumpPath)) { foreach (ClrInfo version in dataTarget.ClrVersions) { Console.WriteLine("Found CLR Version: " + version.Version); // This is the data needed to request the dac from the symbol server: DacInfo dacInfo = version.DacInfo; Console.WriteLine("Filesize: {0:X}", dacInfo.IndexFileSize); Console.WriteLine("Timestamp: {0:X}", dacInfo.IndexTimeStamp); Console.WriteLine("Dac File: {0}", dacInfo.PlatformSpecificFileName); // If we just happen to have the correct dac file installed on the machine, // the "LocalMatchingDac" property will return its location on disk: string dacLocation = version.DacInfo.LocalDacPath;; if (!string.IsNullOrEmpty(dacLocation)) { Console.WriteLine("Local dac location: " + dacLocation); } ClrInfo runtimeInfo = dataTarget.ClrVersions[0]; // just using the first runtime ClrRuntime runtime = runtimeInfo.CreateRuntime(); // You may also download the dac from the symbol server, which is covered // in a later section of this tutorial. foreach (ClrAppDomain domain in runtime.AppDomains) { Console.WriteLine("ID: {0}", domain.Id); Console.WriteLine("Name: {0}", domain.Name); Console.WriteLine("Address: {0}", domain.Address); foreach (ClrModule module in domain.Modules) { Console.WriteLine("Module: {0}", module.Name); } foreach (ClrThread thread in runtime.Threads) { if (!thread.IsAlive) { continue; } Console.WriteLine("Thread {0:X}:", thread.OSThreadId); foreach (ClrStackFrame frame in thread.EnumerateStackTrace()) { Console.WriteLine("Stack Name: " + frame.ToString()); Console.WriteLine("{0,12:X} {1,12:X} {2}", frame.StackPointer, frame.InstructionPointer, frame); } Console.WriteLine(); Console.WriteLine("{0,12} {1,12} {2,12} {3,12} {4,4} {5}", "Start", "End", "CommittedMemory", "ReservedMemory", "Heap", "Type"); foreach (ClrSegment segment in runtime.Heap.Segments) { string type; if (segment.IsEphemeralSegment) { type = "Ephemeral"; } else if (segment.IsLargeObjectSegment) { type = "Large"; } else { type = "Gen2"; } Console.WriteLine("{0,12:X} {1,12:X} {2,12:X} {3,12:X} {4,4} {5}", segment.Start, segment.End, segment.CommittedMemory, segment.ReservedMemory, segment.LogicalHeap, type); } foreach (var item in (from seg in runtime.Heap.Segments group seg by seg.LogicalHeap into g orderby g.Key select new { Heap = g.Key, Size = g.Sum(p => (uint)p.Length) })) { Console.WriteLine("Heap {0,2}: {1:n0} bytes", item.Heap, item.Size); } } foreach (var handle in runtime.EnumerateHandles()) { string objectType = runtime.Heap.GetObjectType(handle.Object).Name; Console.WriteLine("{0,12:X} {1,12:X} {2,12} {3}", handle.Address, handle.Object, handle.GetType(), objectType); } if (!runtime.Heap.CanWalkHeap) { Console.WriteLine("Cannot walk the heap!"); } else { foreach (ClrSegment seg in runtime.Heap.Segments) { for (ulong obj = seg.FirstObjectAddress; obj != 0; obj = seg.GetNextObjectAddress(obj)) { ClrType type = runtime.Heap.GetObjectType(obj); // If heap corruption, continue past this object. if (type == null) { continue; } int size = type.StaticSize; Console.WriteLine("{0,12:X} {1,8:n0} {2,1:n0} {3}", obj, size, seg.GetGeneration(obj), type.Name); } } } // https://github.com/microsoft/clrmd/blob/master/doc/WalkingTheHeap.md#walking-objects-without-walking-the-segments if (!runtime.Heap.CanWalkHeap) { Console.WriteLine("Cannot walk the heap!"); } else { foreach (ulong obj in runtime.Heap.EnumerateObjects()) { ClrType type = runtime.Heap.GetObjectType(obj); // If heap corruption, continue past this object. if (type == null) { continue; } int size = type.StaticSize; Console.WriteLine("{0,12:X} {1,8:n0} {2,1:n0} {3}", obj, size, type.GCDesc, type.Name); } } } } } }