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(); }
public bool Attach(Process process, string dacFile = null, uint attachTimeout = DefaultAttachTimeout) { if (process == null) { throw new ArgumentNullException("process"); } _process = process; if (_dataTarget != null) { _output.Error(String.Format("Already attached to process PID={0} Name={1}", _process.Id, _process.ProcessName)); return false; } _output.Info(String.Format("Attaching to process PID={0}", process.Id)); try { _dataTarget = DataTarget.AttachToProcess(process.Id, attachTimeout); //make sure we dont kill the process on exit } catch (Exception exception) { //TODO: Be more specific, dont catch all exceptions _output.Error("Could not attach to the process."); throw; } if (_dataTarget == null) { //TODO: Be more specific, what exactly does it mean? _output.Error("Could not attach to the process."); _process = null; return false; } _dataTarget.DebuggerInterface.SetProcessOptions(DEBUG_PROCESS.DETACH_ON_EXIT); if (_dataTarget.ClrVersions.Count == 0) { var msg = String.Format( "Process PID={0} Name={1} does not seem to have CLR loaded. Is it an unmanaged process?", _process.Id, _process.ProcessName); _output.Error(msg); Detach(); return false; } if (_dataTarget.ClrVersions.Count > 1) { //TODO: multiple CLRs found present user with choice? var msg = String.Format("Multiple CLR versions loaded. Proceeding with first version."); _output.Warning(msg); } _clrInfo = _dataTarget.ClrVersions[0]; _output.Info(String.Format("Using CLR Version={0} DACFileName={1}", _clrInfo.Version, _clrInfo.DacInfo.FileName)); string dacLocation; if(String.IsNullOrWhiteSpace(dacFile)) { dacLocation = _clrInfo.TryGetDacLocation(); } else { dacLocation = dacFile; _output.Info(String.Format("Using DacFile={0}", dacFile)); } if (String.IsNullOrWhiteSpace(dacLocation)) { //TODO: Check filepath, display meaningful message _output.Error("Could not automatically locate Data Access Component (mscordacwks.dll). This may mean that bitness or CLR versions do not match. " + "You may specify file location manually eg. ClrDiag.Attach(PID, @\"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\mscordacwks.dll\""); Detach(); return false; } ClrRuntime runtime = _dataTarget.CreateRuntime(dacLocation); if (runtime == null) { //TODO: add more meaningful information _output.Error("Unable to get CLR information."); Detach(); } _output.Success(String.Format("Succesfully attached to process PID={0} Name={1}", _process.Id, _process.ProcessName)); Clr = runtime; return true; }
private ClrMDSession(DataTarget target, string dacFile) : this(target, target.CreateRuntime(dacFile)) { }
private ClrRuntime SetupClrRuntime(DataTarget dataTarget) { var version = dataTarget.ClrVersions.Single(); logger?.WriteLine($"\nCLR Version: {version.Version} ({version.Flavor}), Dac: {version.DacInfo}"); var dacFileName = version.TryDownloadDac(); logger?.WriteLine($"DacFile: {Path.GetFileName(dacFileName)}"); logger?.WriteLine($"DacPath: {Path.GetDirectoryName(dacFileName)}"); ClrRuntime runtime = dataTarget.CreateRuntime(dacFileName); return runtime; }
private ProcessAnalyzer(DataTarget dataTarget, ClrRuntime runtime) { _debugClient = dataTarget.DebuggerInterface; _dataReader = dataTarget.DataReader; _runtime = runtime; _globalConfig = Config.GetInstance(); _isDisposed = false; }
private void AttachToProcess() { VerifyTargetProcessArchitecture(); _target = DataTarget.AttachToProcess(_processId, ATTACH_TIMEOUT, AttachFlag.Passive); _context.WriteInfoLine("Attached to process {0}, architecture {1}, {2} CLR versions detected.", _processId, _target.Architecture, _target.ClrVersions.Count); _context.ProcessId = _processId; _context.TargetType = TargetType.LiveProcess; }
/// <summary> /// Converts the specified data target. /// </summary> /// <param name="dataTarget">The data target.</param> /// <returns>IDataTarget.</returns> public IDataTarget Convert(ClrMd.DataTarget dataTarget) { if (dataTarget == null) { return(null); } var item = new DataTargetAdapter(this, dataTarget); return(Cache.GetOrAdd <IDataTarget>(dataTarget, () => item, () => item.Setup())); }
public TriageInformation GetTriageInformation(CommandExecutionContext context) { using (_dbgEngTarget = context.CreateTemporaryDbgEngTarget()) { FillModuleInformation(); FillMemoryUsageInformation(context); FillFaultingThreadAndModuleInformation(context); } return _triageInformation; }
internal bool CheckTargetBitness(DataTarget target) { bool resut = true; if (Environment.Is64BitProcess && target.Architecture != Architecture.Amd64) { SetError("Unexpected architecture. Process runs as x64"); resut = false; } return resut; }
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 MiniDumper(string dumpFolder, int pid, string processName, TextWriter logger, DumpType dumpType, bool writeAsync, string filter) { this.dumpFolder = dumpFolder; this.pid = pid; this.processName = processName; this.logger = logger; this.dumpType = dumpType; this.writeAsync = writeAsync; this.rgxFilter = new Regex((filter ?? "*").Replace("*", ".*").Replace('?', '.'), RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase); this.target = DataTarget.AttachToProcess(pid, 1000, AttachFlag.Passive); }
public BlockingObjectsStrategy( ClrRuntime runtime, UnifiedStackTraces unifiedStackTraces = null, DataTarget dataTarget = null) { _runtime = runtime; _unifiedStackTraces = unifiedStackTraces; _dataTarget = dataTarget; if (_dataTarget != null) { if (_dataTarget.Architecture == Architecture.X86) { _stackWalker = new StackWalkerStrategy_x86(_runtime); } _dataReader = _dataTarget.DataReader; _debugClient = _dataTarget.DebuggerInterface; } }
public DumpAnalyzer(string dumpPath) { _target = DataTarget.LoadCrashDump(dumpPath); _target.SymbolLocator.SymbolPath = Environment.GetEnvironmentVariable("_NT_SYMBOL_PATH"); if (_target.Architecture == Architecture.Amd64 && !Environment.Is64BitProcess) { throw new ApplicationException("Architecture doesn't match. Run this with X64 version."); } if (_target.ClrVersions.Count > 0) { ClrInfo dacVersion = _target.ClrVersions[0]; _runtime = dacVersion.CreateRuntime(); // CreateRuntime() tries to find the DAC on disk and then consults // the symbol server if necessary. If all fails, it throws an exception. } }
public RuntimeBase(ClrInfo info, DataTarget dataTarget, DacLibrary lib) { Debug.Assert(lib != null); Debug.Assert(lib.InternalDacPrivateInterface != null); ClrInfo = info; _dataTarget = dataTarget; DacLibrary = lib; _dacInterface = DacLibrary.InternalDacPrivateInterface; InitApi(); _dacInterface.Flush(); IGCInfo data = GetGCInfo(); if (data != null) { ServerGC = data.ServerMode; HeapCount = data.HeapCount; CanWalkHeap = data.GCStructuresValid; } _dataReader = dataTarget.DataReader; }
public DebugServices(IntPtr ptrClient) { DebugClient = (IDebugClient)Marshal.GetUniqueObjectForIUnknown(ptrClient); DataTarget = RuntimeDataTarget.CreateFromDebuggerInterface(DebugClient); Output = new Output(DebugClient); }
private void OpenDumpFile() { if (!File.Exists(_dumpFile)) { Bail("The specified dump file '{0}' does not exist.", _dumpFile); } _target = DataTarget.LoadCrashDump(_dumpFile, CrashDumpReader.ClrMD); _context.WriteInfo("Opened dump file '{0}', architecture {1}, {2} CLR versions detected.", _dumpFile, _target.Architecture, _target.ClrVersions.Count); _context.DumpFile = _dumpFile; _context.TargetType = _target.IsHeapAvailable ? TargetType.DumpFile : TargetType.DumpFileNoHeap; if (!_target.IsHeapAvailable) { _context.WriteWarning( "This dump does not have heap information present. Most commands will not work. " + "Basic triage commands such as !pe, !clrstack, !threads are still available."); } if (_target.IsMinidump) { _context.WriteWarning( "This dump is a minidump, which means it's possible that module contents were " + "not included in the file. To get good information, make sure to put your modules " + "(.exe/.dll files) on the symbol path, not just the symbols (.pdb files)."); } }
internal DacLibrary(DataTarget dataTarget, IntPtr pUnk) { InternalDacPrivateInterface = new ClrDataProcess(this, pUnk); }
private void SetStrategy() { if (_context.TargetType == TargetType.DumpFile || _context.TargetType == TargetType.DumpFile) { _temporaryDbgEngTarget = _context.CreateTemporaryDbgEngTarget(); _unifiedStackTraces = new UnifiedStackTraces(_temporaryDbgEngTarget.DebuggerInterface, _context); _blockingObjectsStrategy = new DumpFileBlockingObjectsStrategy(_context.Runtime, _unifiedStackTraces, _temporaryDbgEngTarget); _threads.AddRange(_unifiedStackTraces.Threads.Select(ti => _blockingObjectsStrategy.GetThreadWithBlockingObjects(ti))); } else { _blockingObjectsStrategy = new LiveProcessBlockingObjectsStrategy(_context.Runtime); // Currently, we are only enumerating the managed threads because we don't have // an alternative source of information for threads in live processes. In the future, // we can consider using System.Diagnostics or some other means of enumerating threads // in live processes. _threads.AddRange(_context.Runtime.Threads.Select(thr => _blockingObjectsStrategy.GetThreadWithBlockingObjects(thr))); } }
public RunInSeparateAppDomain(int pid, int clrVersionIndex, string dacLocation, IPrinter printer) { _target = DataTarget.AttachToProcess(pid, AttachTimeout, AttachFlag.Passive); CreateRuntime(clrVersionIndex, dacLocation); _printer = printer; }
public MDTarget(object iDebugClient) { m_target = DataTarget.CreateFromDebuggerInterface((IDebugClient)iDebugClient); }
public DumpFileBlockingObjectsStrategy(ClrRuntime runtime, UnifiedStackTraces unifiedStackTraces, DataTarget dataTarget) : base(runtime, unifiedStackTraces, dataTarget) { if (_dataTarget != null) { try { _handles = runtime.DataTarget.DataReader.EnumerateHandles().ToList(); } catch (ClrDiagnosticsException) { // The dump file probably doesn't contain the handle stream. } } }
/// <summary> /// Used for dump file analysis /// </summary> public ProcessAnalyzer(DataTarget dataTarget, ClrRuntime runtime, string pathToDumpFile) : this(dataTarget, runtime) { var dumpStrategy = new DumpFileQuerierStrategy(pathToDumpFile, _runtime, _debugClient, _dataReader); _processQuerierStrategy = dumpStrategy; _globalConfig.Init(_processQuerierStrategy.CPUArchitechture, dumpStrategy.SystemInfo); }
/// <summary> /// Used for live process analysis /// </summary> public ProcessAnalyzer(DataTarget dataTarget, ClrRuntime runtime, uint pid) : this(dataTarget, runtime) { _pid = pid; _processQuerierStrategy = new LiveProcessQuerierStrategy(_debugClient, _dataReader, runtime); _globalConfig.Init(_processQuerierStrategy.CPUArchitechture); }
private static ClrRuntime CreateRuntime(DataTarget target) { string dacLocation = null; foreach (ClrInfo version in target.ClrVersions) { Console.WriteLine("Found CLR Version: " + version.Version.ToString()); dacLocation = LoadCorrectDacForMemoryDump(version); } var runtimeInfo = target.ClrVersions[0]; // just using the first runtime ClrRuntime runtime = null; try { if (string.IsNullOrEmpty(dacLocation)) { Console.WriteLine(dacLocation); runtime = runtimeInfo.CreateRuntime(); } else { runtime = runtimeInfo.CreateRuntime(dacLocation); } } catch (InvalidOperationException ex) { Console.WriteLine("\n" + ex); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("\nEnsure that this program is compliled for the same architecture as the memory dump (i.e. 32-bit or 64-bit)"); Console.WriteLine(String.Format(".NET Memory Dump Heap Analyser is compiled as {0}-bit\n", Environment.Is64BitProcess ? "64" : "32")); Console.ResetColor(); return null; } catch (Exception ex) { Console.WriteLine("\n" + ex); Console.WriteLine("\nUnable to process the Memory Dump file!?"); return null; } return runtime; }
private DebugSession(DataTarget dataTarget) { this.DataTarget = dataTarget; }
public MDTarget(string crashdump) { // TODO: Complete member initialization m_target = DataTarget.LoadCrashDump(crashdump); }
/// <summary> /// Creates a persistent DbgEng DataTarget that can be used to execute multiple /// commands (remembers state). While this DataTarget is in place, msos is placed /// in native DbgEng "mode", and accepts only DbgEng commands. /// </summary> public void EnterDbgEngNativeMode() { _dbgEngDataTarget = CreateDbgEngDataTargetImpl(); }
public RunInSeparateAppDomain(string dumpFile, int clrVersionIndex, string dacLocation, IPrinter printer) { _target = DataTarget.LoadCrashDump(dumpFile, CrashDumpReader.ClrMD); CreateRuntime(clrVersionIndex, dacLocation); _printer = printer; }
internal ClrInfo(DataTarget dt, ClrFlavor flavor, ModuleInfo module, ulong runtimeInfo) { DataTarget = dt ?? throw new ArgumentNullException(nameof(dt)); Flavor = flavor; ModuleInfo = module ?? throw new ArgumentNullException(nameof(module)); IsSingleFile = runtimeInfo != 0; List <DebugLibraryInfo> artifacts = new List <DebugLibraryInfo>(8); OSPlatform currentPlatform = GetCurrentPlatform(); OSPlatform targetPlatform = dt.DataReader.TargetPlatform; Architecture currentArch = RuntimeInformation.ProcessArchitecture; Architecture targetArch = dt.DataReader.Architecture; string?dacCurrentPlatform = GetDacFileName(flavor, currentPlatform); string?dacTargetPlatform = GetDacFileName(flavor, targetPlatform); string?dbiCurrentPlatform = GetDbiFileName(flavor, currentPlatform); string?dbiTargetPlatform = GetDbiFileName(flavor, targetPlatform); if (IsSingleFile) { ClrRuntimeInfo info = DataTarget.DataReader.Read <ClrRuntimeInfo>(runtimeInfo); if (info.IsValid) { if (dt.DataReader.TargetPlatform == OSPlatform.Windows) { IndexTimeStamp = info.RuntimePEProperties.TimeStamp; IndexFileSize = info.RuntimePEProperties.FileSize; if (dacTargetPlatform is not null) { var dacProp = info.DacPEProperties; if (dacProp.TimeStamp != 0 && dacProp.FileSize != 0) { artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dac, dacTargetPlatform, targetArch, SymbolProperties.Self, dacProp.FileSize, dacProp.TimeStamp)); } } if (dbiTargetPlatform is not null) { var dbiProp = info.DbiPEProperties; if (dbiProp.TimeStamp != 0 && dbiProp.FileSize != 0) { artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dbi, dbiTargetPlatform, targetArch, SymbolProperties.Self, dbiProp.FileSize, dbiProp.TimeStamp)); } } } else { BuildId = info.RuntimeBuildId; if (dacTargetPlatform is not null) { var dacBuild = info.DacBuildId; if (!dacBuild.IsDefaultOrEmpty) { artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dac, dacTargetPlatform, targetArch, targetPlatform, SymbolProperties.Self, dacBuild)); } } if (dbiTargetPlatform is not null) { var dbiBuild = info.DbiBuildId; if (!dbiBuild.IsDefaultOrEmpty) { artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dbi, dbiTargetPlatform, targetArch, targetPlatform, SymbolProperties.Self, dbiBuild)); } } } } // We don't actually know the version of single file CLR since the version of the module would be the user's app version Version = new Version(); } else { IndexTimeStamp = module.IndexTimeStamp; IndexFileSize = module.IndexFileSize; BuildId = module.BuildId; Version = module.Version; } // Long-name dac if (dt.DataReader.TargetPlatform == OSPlatform.Windows && Version.Major != 0) { artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dac, GetWindowsLongNameDac(flavor, currentArch, targetArch, Version), currentArch, SymbolProperties.Coreclr, IndexFileSize, IndexTimeStamp)); } // Short-name dac under CLR's properties if (targetPlatform == currentPlatform) { // We are debugging the process on the same operating system. if (dacCurrentPlatform is not null) { bool foundLocalDac = false; // Check if the user has the same CLR installed locally, and if so string?directory = Path.GetDirectoryName(module.FileName); if (!string.IsNullOrWhiteSpace(directory)) { string potentialClr = Path.Combine(directory, Path.GetFileName(module.FileName)); if (File.Exists(potentialClr)) { try { using PEImage peimage = new PEImage(File.OpenRead(potentialClr)); if (peimage.IndexFileSize == IndexFileSize && peimage.IndexTimeStamp == IndexTimeStamp) { string dacFound = Path.Combine(directory, dacCurrentPlatform); if (File.Exists(dacFound)) { dacCurrentPlatform = dacFound; foundLocalDac = true; } } } catch { } } } if (IndexFileSize != 0 && IndexTimeStamp != 0) { var dacLibraryInfo = new DebugLibraryInfo(DebugLibraryKind.Dac, dacCurrentPlatform, targetArch, SymbolProperties.Coreclr, IndexFileSize, IndexTimeStamp); if (foundLocalDac) { artifacts.Insert(0, dacLibraryInfo); } else { artifacts.Add(dacLibraryInfo); } } if (!BuildId.IsDefaultOrEmpty) { var dacLibraryInfo = new DebugLibraryInfo(DebugLibraryKind.Dac, dacCurrentPlatform, targetArch, targetPlatform, SymbolProperties.Coreclr, BuildId); if (foundLocalDac) { artifacts.Insert(0, dacLibraryInfo); } else { artifacts.Add(dacLibraryInfo); } } } if (dbiCurrentPlatform is not null) { if (IndexFileSize != 0 && IndexTimeStamp != 0) { artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dbi, dbiCurrentPlatform, targetArch, SymbolProperties.Coreclr, IndexFileSize, IndexTimeStamp)); } if (!BuildId.IsDefaultOrEmpty) { artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dbi, dbiCurrentPlatform, targetArch, targetPlatform, SymbolProperties.Coreclr, BuildId)); } } } else { // We are debugging the process on a different operating system. if (IndexFileSize != 0 && IndexTimeStamp != 0) { // We currently only support cross-os debugging on windows targeting linux or os x runtimes. So if we have windows properties, // then we only generate one artifact (the target one). if (dacTargetPlatform is not null) { artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dac, dacTargetPlatform, targetArch, SymbolProperties.Coreclr, IndexFileSize, IndexTimeStamp)); } if (dbiTargetPlatform is not null) { artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dbi, dbiTargetPlatform, targetArch, SymbolProperties.Coreclr, IndexFileSize, IndexTimeStamp)); } } if (!BuildId.IsDefaultOrEmpty) { if (dacTargetPlatform is not null) { artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dac, dacTargetPlatform, targetArch, targetPlatform, SymbolProperties.Coreclr, BuildId)); } if (dbiTargetPlatform is not null) { artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dbi, dbiTargetPlatform, targetArch, targetPlatform, SymbolProperties.Coreclr, BuildId)); } if (currentPlatform == OSPlatform.Windows) { // If we are running from Windows, we can target Linux and OS X dumps. We do build cross-os, cross-architecture debug libraries to run on Windows x64 or x86 if (dacCurrentPlatform is not null) { artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dac, dacCurrentPlatform, currentArch, currentPlatform, SymbolProperties.Coreclr, BuildId)); } if (dbiCurrentPlatform is not null) { artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dbi, dbiCurrentPlatform, currentArch, currentPlatform, SymbolProperties.Coreclr, BuildId)); } } } } // Windows CLRDEBUGINFO resource IResourceNode?resourceNode = module.ResourceRoot?.GetChild("RCData")?.GetChild("CLRDEBUGINFO")?.Children.FirstOrDefault(); if (resourceNode is not null) { CLR_DEBUG_RESOURCE resource = resourceNode.Read <CLR_DEBUG_RESOURCE>(0); if (resource.dwVersion == 0) { if (dacTargetPlatform is not null && resource.dwDacTimeStamp != 0 && resource.dwDacSizeOfImage != 0) { artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dac, dacTargetPlatform, targetArch, SymbolProperties.Self, resource.dwDacSizeOfImage, resource.dwDacTimeStamp)); } if (dbiTargetPlatform is not null && resource.dwDbiTimeStamp != 0 && resource.dwDbiSizeOfImage != 0) { artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dbi, dbiTargetPlatform, targetArch, SymbolProperties.Self, resource.dwDbiSizeOfImage, resource.dwDbiTimeStamp)); } } } // Do NOT take a dependency on the order of enumerated libraries. I reserve the right to change this at any time. var ordered = from artifact in EnumerateUnique(artifacts) orderby artifact.Kind, Path.GetFileName(artifact.FileName) == artifact.FileName, // if we have a full local path, put it first artifact.ArchivedUnder select artifact; DebuggingLibraries = ordered.ToImmutableArray(); }
internal ClrInfo(DataTarget dt, ClrFlavor flavor, ModuleInfo module, DacInfo dacInfo, string dacLocation) { Debug.Assert(dacInfo != null); Flavor = flavor; DacInfo = dacInfo; ModuleInfo = module; module.IsRuntime = true; _dataTarget = dt; _dacLocation = dacLocation; }
private static bool IsClrModule64Bit(DataTarget target) { var clrModule = target.EnumerateModules().FirstOrDefault(item => "clr.dll".Equals(Path.GetFileName(item.FileName), StringComparison.OrdinalIgnoreCase)); if (clrModule == null) throw new InvalidOperationException("Unable to find clr.dll module in dump file."); return clrModule.FileName.IndexOf("Framework64", StringComparison.OrdinalIgnoreCase) != -1; }
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(); }
private static void PrintDiagnosticInfo(DataTarget dt, ClrRuntime runtime, ClrHeap heap) { Console.WriteLine("DataTarget Info:"); Console.WriteLine(" ClrVersions: " + String.Join(", ", dt.ClrVersions)); Console.WriteLine(" IsMinidump: " + dt.IsMinidump); Console.WriteLine(" Architecture: " + dt.Architecture); Console.WriteLine(" PointerSize: " + dt.PointerSize); Console.WriteLine(" SymbolPath: " + dt.GetSymbolPath()); Console.WriteLine("ClrRuntime Info:"); Console.WriteLine(" ServerGC: " + runtime.ServerGC); Console.WriteLine(" HeapCount: " + runtime.HeapCount); Console.WriteLine(" Thread Count: " + runtime.Threads.Count); Console.WriteLine("ClrRuntime Modules:"); foreach (var module in runtime.EnumerateModules()) { Console.WriteLine(" {0,26} Id:{1}, {2,10:N0} bytes @ 0x{3:X8}", Path.GetFileName(module.FileName), module.AssemblyId, module.Size, module.ImageBase); } Console.WriteLine("ClrHeap Info:"); Console.WriteLine(" TotalHeapSize: " + heap.TotalHeapSize); Console.WriteLine(" Segments: " + heap.Segments.Count); Console.WriteLine(" Gen0 Size: " + heap.GetSizeByGen(0)); Console.WriteLine(" Gen1 Size: " + heap.GetSizeByGen(1)); Console.WriteLine(" Gen2 Size: " + heap.GetSizeByGen(2)); Console.WriteLine(" Gen3 Size: " + heap.GetSizeByGen(3)); }
public void ExitDbgEngNativeMode() { _dbgEngDataTarget.Dispose(); _dbgEngDataTarget = null; }
public void Detach() { var name = _process.ProcessName; var pid = _process.Id; _process = null; _clrInfo = null; Clr = null; if (_dataTarget == null) { return; } _dataTarget.DebuggerInterface.DetachProcesses(); _dataTarget.Dispose(); _dataTarget = null; _output.Success(String.Format("Successfully detached from process PID={0} Name={1}", pid, name)); }