private ClrRuntime CreateRuntime(ClrInfo clrInfo) { if (_commandLineOptions.DacPath != null) { return(clrInfo.CreateRuntime(_commandLineOptions.DacPath.FullName, _commandLineOptions.IgnoreDacMismatch)); } else { return(clrInfo.CreateRuntime()); } }
private static void PrintGen(ClrInfo clr) { Dictionary <string, int> stringDupesDict = new Dictionary <string, int>(); ClrRuntime runtime = clr.CreateRuntime(); if (!runtime.Heap.CanWalkHeap) { Console.WriteLine("Cannot walk the heap!"); } else { 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($"{type} object range: {segment.ObjectRange} committed memory range: {segment.CommittedMemory} reserved memory range: {segment.ReservedMemory}"); } } Console.WriteLine("Done"); }
/// <summary> /// Walks the heap and checks all objects for string type. /// </summary> /// <returns>The number of found strings.</returns> public static int GetStringCount() { int numberOfStrings = 0; Process currentProcess = Process.GetCurrentProcess(); using (DataTarget dataTarget = DataTarget.AttachToProcess(currentProcess.Id, 10000, AttachFlag.Passive)) { ClrInfo clrVersion = dataTarget.ClrVersions.First(); ClrRuntime runtime = clrVersion.CreateRuntime(); ClrHeap heap = runtime.Heap; if (!heap.CanWalkHeap) { return(0); } foreach (ulong ptr in heap.EnumerateObjectAddresses()) { ClrType type = heap.GetObjectType(ptr); if (type == null || type.IsString == false) { continue; } numberOfStrings++; } } return(numberOfStrings); }
public async Task InvokeAsync(HttpContext context) { ClrInfo runtimeInfo = _dataTargetProvider.GetDataTarget().ClrVersions[0]; ClrRuntime runtime = runtimeInfo.CreateRuntime(); var stats = from o in runtime.Heap.EnumerateObjects() let t = o.Type group o by t into g let size = g.Sum(o => (uint)o.Size) select new { Name = g.Key.Name, Size = size, Count = g.Count() }; var content = TableBuilder.CreateDataTable("Heap", stats.OrderByDescending(f => f.Size).Select(f => new { Size = f.Size, Count = f.Count.ToString(), Name = f.Name })); await _next(context); await context.Response.WriteAsync(content); }
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); }
/// <summary> /// ClrRuntime service factory /// </summary> private ClrRuntime CreateRuntime(DataTarget target) { ClrRuntime runtime; if (target.ClrVersions.Count != 1) { throw new InvalidOperationException("More or less than 1 CLR version is present"); } ClrInfo clrInfo = target.ClrVersions[0]; string dacFilePath = GetDacFile(clrInfo); try { runtime = clrInfo.CreateRuntime(dacFilePath); } catch (DllNotFoundException ex) { // This is a workaround for the Microsoft SDK docker images. Can fail when clrmd uses libdl.so // to create a symlink to and load the DAC module. if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { throw new DllNotFoundException("Problem initializing CLRMD. Try installing libc6-dev (apt-get install libc6-dev) to work around this problem.", ex); } else { throw; } } return(runtime); }
private void walkTheHeapToolStripMenuItem_Click(object sender, EventArgs e) { List <String> managedObjects = new List <String>(); foreach (DataGridViewRow row in dataGridViewMain.SelectedRows) { managedObjects.Add(((ManagedObject)row.DataBoundItem).ObjectName); } if (Process != null) { using (DataTarget dataTarget = DataTarget.AttachToProcess(Process.Id, dataTargetTimeOut, dataTargetAttachFlag)) { ClrInfo clrVersion = dataTarget.ClrVersions.First(); ClrRuntime runtime = clrVersion.CreateRuntime(); RetentionTreeViewer r = new RetentionTreeViewer(runtime, managedObjects); r.ShowDialog(this); } } else { RetentionTreeViewer r = new RetentionTreeViewer(null, managedObjects); r.ShowDialog(this); } }
private static void LoadDump(string fileName, string search) { _target?.Dispose(); _target = DataTarget.LoadCrashDump(fileName); ClrInfo runtimeInfo = _target.ClrVersions[0]; _runtime = runtimeInfo.CreateRuntime(); var heap = _runtime.Heap; if (!heap.CanWalkHeap) { Console.WriteLine("Cannot walk the heap!"); } else { _strings.Clear(); foreach (var item in heap.EnumerateObjects() .Where(o => o.Type != null) .Where(o => o.Type.IsString) .Select(o => new { Obj = o, Val = o.Type.GetValue(o.Address).ToString() }) .Where(arg => arg.Val.StartsWith(search)) ) { _strings.Add(item.Obj); Console.WriteLine(item.Val + " " + item.Obj.HexAddress); } } }
static CustomDebugManager() { TaleWorlds.Library.Debug.DebugManager = Instance; var pid = -1; using (var proc = Process.GetCurrentProcess()) pid = proc.Id; _attachedDt = DataTarget.PassiveAttachToProcess(pid); _inProcDt = new DataTarget(new InProcDataReader(_attachedDt.DataReader)); _clrInfo = _inProcDt.ClrVersions.Single(); _debugRt = _clrInfo.CreateRuntime(); /* * foreach (var thread in _debugRt.Threads) { * if (thread.IsUnstarted) * continue; * * var i = 0; * foreach (var frame in thread.EnumerateStackTrace()) { * if (i++ < 100) * continue; * * Debugger.Break(); * break; * } * } */ }
/// <summary> /// Create ClrRuntime helper /// </summary> private ClrRuntime CreateRuntime() { if (_clrRuntime == null) { string dacFilePath = GetDacFilePath(); if (dacFilePath != null) { Trace.TraceInformation($"Creating ClrRuntime #{Id} {dacFilePath}"); try { // Ignore the DAC version mismatch that can happen because the clrmd ELF dump reader // returns 0.0.0.0 for the runtime module that the DAC is matched against. _clrRuntime = _clrInfo.CreateRuntime(dacFilePath, ignoreMismatch: true); } catch (Exception ex) when (ex is DllNotFoundException || ex is FileNotFoundException || ex is InvalidOperationException || ex is InvalidDataException || ex is ClrDiagnosticsException) { Trace.TraceError("CreateRuntime FAILED: {0}", ex.ToString()); } } else { Trace.TraceError($"Could not find or download matching DAC for this runtime: {RuntimeModule.FileName}"); } } return(_clrRuntime); }
public static ClrRuntime CreateRuntimeAndGetDacLocation(this DataTarget target, ClrInfo info, out string dacLocation) { dacLocation = info.LocalMatchingDac; if (dacLocation != null) { return(info.CreateRuntime()); } dacLocation = target.SymbolLocator.FindBinary(info.DacInfo); if (dacLocation != null) { return(info.CreateRuntime(dacLocation)); } return(null); }
private static ClrModel BuildClrModel(ClrInfo clrInfo) { var runtime = clrInfo.CreateRuntime(); var clrModel = new ClrModel { Version = CreateVersion(clrInfo), PointerSize = runtime.PointerSize, ServerGC = runtime.ServerGC, HeapCount = runtime.HeapCount, DacLocation = runtime.ClrInfo.LocalMatchingDac, //ClrObjects = BuildClrObjects(runtime), RootRefs = BuildRootRefs(runtime), }; //PrintAppDomains(runtime, sw); //PrintModules(runtime, sw); //PrintThreadS(runtime, sw); //PrintSegments(runtime, sw); //PrintGCHandles(runtime, sw); //PrintHeapSegments(runtime, sw); //PrintLogicHeapBalance(runtime, sw); //PrintManagedObjectsBySegment(runtime, sw); //PrintManagedObjects(runtime, sw); return(clrModel); }
public async Task InvokeAsync(HttpContext context) { await _next(context); ClrInfo runtimeInfo = _dataTargetProvider.GetDataTarget().ClrVersions[0]; ClrRuntime runtime = runtimeInfo.CreateRuntime(); if (context.Request.Query.TryGetValue("id", out StringValues value)) { var threadId = value.ToString(); ClrThread thread = runtime.Threads.FirstOrDefault(f => f.OSThreadId.ToString() == threadId); if (thread != null) { string content = TableBuilder.CreateDataTable($"Stack for Thread {threadId}", thread.StackTrace.Select(f => new { InstructionPointer = TableColumn.Wrap(f.InstructionPointer).Format("{0,12:X}"), StackPointer = TableColumn.Wrap(f.StackPointer).Format("{0,12:X}"), DisplayString = f.DisplayString, Method = f.Method, ModuleName = f.ModuleName, })); await context.Response.WriteAsync(content); } } }
/// <summary> /// Refresh all assemblies in given TreeView. /// </summary> /// <param name="tvAssemblies">Current TreeView.</param> public static void RefreshAssemblies(TreeView tvAssemblies) { tvAssemblies.Nodes.Clear(); int pid = Process.GetCurrentProcess().Id; DT = DataTarget.AttachToProcess(pid, 5000, AttachFlag.Passive); foreach (ClrInfo clrVersion in DT.ClrVersions) { TreeElement clrNode = new TreeElement("CLR", clrVersion); tvAssemblies.Nodes.Add(clrNode); ClrInfo clrInfo = (ClrInfo)clrNode.Object; ClrRuntime runtime = clrInfo.CreateRuntime(); foreach (ClrModule module in runtime.Modules) { TreeElement moduleNode = new TreeElement("Module", module); clrNode.Nodes.Add(moduleNode); foreach (ClrType clrType in module.EnumerateTypes()) { TreeElement typeNode = new TreeElement("Type", clrType); moduleNode.Nodes.Add(typeNode); } } } }
private static ClrRuntime CreateRuntime(string dump, string dac) { // Create the data target. This tells us the versions of CLR loaded in the target process. DataTarget dataTarget = DataTarget.LoadCrashDump(dump); // Now check bitness of our program/target: bool isTarget64Bit = dataTarget.PointerSize == 8; if (Environment.Is64BitProcess != isTarget64Bit) throw new Exception(string.Format("Architecture mismatch: Process is {0} but target is {1}", Environment.Is64BitProcess ? "64 bit" : "32 bit", isTarget64Bit ? "64 bit" : "32 bit")); // Note I just take the first version of CLR in the process. You can loop over every loaded // CLR to handle the SxS case where both v2 and v4 are loaded in the process. ClrInfo version = dataTarget.ClrVersions[0]; // Next, let's try to make sure we have the right Dac to load. Note we are doing this manually for // illustration. Simply calling version.CreateRuntime with no arguments does the same steps. if (dac != null && Directory.Exists(dac)) dac = Path.Combine(dac, version.DacInfo.FileName); else if (dac == null || !File.Exists(dac)) dac = dataTarget.SymbolLocator.FindBinary(version.DacInfo); // Finally, check to see if the dac exists. If not, throw an exception. if (dac == null || !File.Exists(dac)) throw new FileNotFoundException("Could not find the specified dac.", dac); // Now that we have the DataTarget, the version of CLR, and the right dac, we create and return a // ClrRuntime instance. return version.CreateRuntime(dac); }
public static void Start(Options options, Process process, IWriter outWriter) { Dictionary <ClrType, HeapStatsEntry> stats = null; IEnumerable <ThreadData> threads = null; using (var dataTarget = DataTarget.AttachToProcess(process.Id, 5000, AttachFlag.Invasive)) { ClrInfo version = dataTarget.ClrVersions.FirstOrDefault(); if (version != null) { var runtime = version.CreateRuntime(); if (options.DumpThreads) { threads = ThreadsDump(runtime); } if (options.DumpStats) { stats = HeapDump(runtime); } if (!string.IsNullOrEmpty(options.DumpHeapByType)) { DumpHeapByType(runtime, options.DumpHeapByType, outWriter); } } if (options.FullDump) { IDebugClient client = dataTarget.DebuggerInterface; var fileName = Path.Combine(options.OutputFolder ?? Environment.CurrentDirectory, GetDumpFileName(process)); outWriter.WriteHint($"Writing memory dump to: {fileName}"); client.WriteDumpFile(fileName, DEBUG_DUMP.DEFAULT); } } if (threads != null) { outWriter.WriteHint("Thread dump:"); foreach (var thread in threads) { outWriter.WriteLine(thread.ToString(), "thread"); } outWriter.WriteHint("Thread dump finished."); } if (stats != null) { outWriter.WriteHint("Heap stats:"); StringBuilder sb = new StringBuilder(); sb.AppendLine(string.Format("{0,12} {1,12} {2}", "Size", "Count", "Type")); foreach (var entry in from entry in stats.Values orderby entry.Size select entry) { sb.AppendLine(string.Format("{0,12:n0} {1,12:n0} {2}", entry.Size, entry.Count, entry.Name)); } outWriter.WriteLine(sb.ToString(), "Heap"); outWriter.WriteHint("Heap stats finished."); } }
public void RuntimeClrInfo() { using DataTarget dt = TestTargets.NestedException.LoadFullDump(); ClrInfo info = dt.ClrVersions.Single(); ClrRuntime runtime = info.CreateRuntime(); Assert.Equal(info, runtime.ClrInfo); }
public static AnalysisContext FromProcessDump(string processDump, string dacPath) { var dataTarget = DataTarget.LoadCrashDump(processDump); ClrInfo runtimeInfo = dataTarget.ClrVersions[0]; // just using the first runtime ClrRuntime runtime = runtimeInfo.CreateRuntime(dacPath, true); return(new AnalysisContext(dataTarget, runtime)); }
//https://github.com/Microsoft/dotnet-samples/tree/master/Microsoft.Diagnostics.Runtime/CLRMD private void objectOverviewToolStripMenuItem_Click(object sender, EventArgs e) { if (Process == null) { return; } saveFileDialogObjects.FileName = String.Format("clrmd_{0:yyyyMMdd_HHmmss}_FieldInfo", DateTime.Now); if (saveFileDialogObjects.ShowDialog() != DialogResult.OK) { return; } if (File.Exists(saveFileDialogObjects.FileName)) { File.Delete(saveFileDialogObjects.FileName); } Cursor.Current = Cursors.WaitCursor; using (DataTarget dataTarget = DataTarget.AttachToProcess(Process.Id, dataTargetTimeOut, dataTargetAttachFlag)) { ClrInfo clrVersion = dataTarget.ClrVersions.First(); ClrRuntime runtime = clrVersion.CreateRuntime(); if (runtime.Heap.CanWalkHeap) { using (StreamWriter writer = new StreamWriter(saveFileDialogObjects.FileName, true, Encoding.UTF8)) { foreach (DataGridViewRow row in dataGridViewMain.SelectedRows) { int cnt = 0; ManagedObject m = row.DataBoundItem as ManagedObject; writer.WriteLine("*********************** {0} ************************", m.ObjectName); writer.WriteLine(); foreach (ulong ptr in runtime.Heap.EnumerateObjectAddresses()) { ClrType type = runtime.Heap.GetObjectType(ptr); if (type == null || type.Name != m.ObjectName) { continue; } writer.WriteLine(ClrMdHelper.GetInfoOfObject(runtime, ptr, type)); writer.WriteLine(); cnt++; } writer.WriteLine("{0}x found in Heap {1}", cnt, m.ObjectName); writer.WriteLine(); writer.WriteLine(); } } } } Cursor.Current = Cursors.Default; }
public void CreationSpecificDac() { using DataTarget dt = TestTargets.NestedException.LoadFullDump(); ClrInfo info = dt.ClrVersions.Single(); DebugLibraryInfo dac = Assert.Single(info.DebuggingLibraries.Where(r => Path.GetFileName(r.FileName) != r.FileName)); using ClrRuntime runtime = info.CreateRuntime(dac.FileName); Assert.NotNull(runtime); }
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); string filePath = @"C:\Users\Ne4to\projects\GitHub\Ne4to\Heartbeat\tests\dumps\AsyncStask.dmp"; string?dacPath = null; bool ignoreMismatch = false; var dataTarget = DataTarget.LoadDump(filePath); ClrInfo clrInfo = dataTarget.ClrVersions[0]; var clrRuntime = dacPath == null ? clrInfo.CreateRuntime() : clrInfo.CreateRuntime(dacPath, ignoreMismatch); var runtimeContext = new RuntimeContext(clrRuntime, filePath); services.AddSingleton(runtimeContext); }
public void Process() { if (myPid != 0) { bool isTargetx64 = ProcessHelper.NativeMethods.Is64Bit(myPid); bool archmatch = (isTargetx64 && Environment.Is64BitProcess) || (!isTargetx64 && !Environment.Is64BitProcess); if (!archmatch) { Console.WriteLine($"PID: {myPid} - Inconsistent process architecture."); return; } } using (DataTarget dataTarget = GetDataTarget()) { foreach (ClrInfo clrVersionInfo in dataTarget.ClrVersions) { ClrInfoCallback?.Invoke(clrVersionInfo); } if (dataTarget.ClrVersions.Count == 0) { Console.WriteLine($"PID: {myPid} - Not a managed executable."); return; } ClrInfo runtimeInfo = dataTarget.ClrVersions[0]; ClrRuntime runtime = runtimeInfo.CreateRuntime(); ClrHeap heap = runtime.Heap; if (!heap.CanWalkHeap) { ClrHeapIsNotWalkableCallback?.Invoke(); return; } foreach (ulong obj in heap.EnumerateObjectAddresses()) { ClrType type = heap.GetObjectType(obj); // If heap corruption, continue past this object. if (type == null) { continue; } if (TypesToDump.Contains(type.Name)) { ClrObjectOfTypeFoundCallback(heap, obj, type.Name); } } } }
public void CreationSpecificDac() { using DataTarget dt = TestTargets.NestedException.LoadFullDump(); ClrInfo info = dt.ClrVersions.Single(); string dac = info.LocalMatchingDac; Assert.NotNull(dac); using ClrRuntime runtime = info.CreateRuntime(dac); Assert.NotNull(runtime); }
public void LoadDump(string fileName) { _target?.Dispose(); _target = DataTarget.LoadCrashDump(fileName); ClrInfo runtimeInfo = _target.ClrVersions[0];//.ClrInfo[0]; // just using the first runtime _runtime = runtimeInfo.CreateRuntime(); LoadObjects(); }
public void LoadDump(Process fileName) { _target?.Dispose(); _target = DataTarget.AttachToProcess(fileName.Id, 5000, AttachFlag.Invasive); ClrInfo runtimeInfo = _target.ClrVersions[0];//.ClrInfo[0]; // just using the first runtime _runtime = runtimeInfo.CreateRuntime(); LoadObjects(); }
/// <summary> /// ClrRuntime service factory /// </summary> private ClrRuntime CreateRuntime(DataTarget target) { ClrInfo clrInfo = null; // First check if there is a .NET Core runtime loaded foreach (ClrInfo clr in target.ClrVersions) { if (clr.Flavor == ClrFlavor.Core) { clrInfo = clr; break; } } // If no .NET Core runtime, then check for desktop runtime if (clrInfo == null) { foreach (ClrInfo clr in target.ClrVersions) { if (clr.Flavor == ClrFlavor.Desktop) { clrInfo = clr; break; } } } if (clrInfo == null) { throw new InvalidOperationException("No CLR runtime is present"); } ClrRuntime runtime; string dacFilePath = GetDacFile(clrInfo); try { // Ignore the DAC version mismatch that can happen on Linux because the clrmd ELF dump // reader returns 0.0.0.0 for the runtime module that the DAC is matched against. This // will be fixed in clrmd 2.0 but not 1.1. runtime = clrInfo.CreateRuntime(dacFilePath, ignoreMismatch: clrInfo.ModuleInfo.BuildId != null); } catch (DllNotFoundException ex) { // This is a workaround for the Microsoft SDK docker images. Can fail when clrmd uses libdl.so // to create a symlink to and load the DAC module. if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { throw new DllNotFoundException("Problem initializing CLRMD. Try installing libc6-dev (apt-get install libc6-dev) to work around this problem.", ex); } else { throw; } } return(runtime); }
/// <summary> /// ClrRuntime service factory /// </summary> private ClrRuntime CreateRuntime(DataTarget target) { ClrInfo clrInfo = null; // First check if there is a .NET Core runtime loaded foreach (ClrInfo clr in target.ClrVersions) { if (clr.Flavor == ClrFlavor.Core) { clrInfo = clr; break; } } // If no .NET Core runtime, then check for desktop runtime if (clrInfo == null) { foreach (ClrInfo clr in target.ClrVersions) { if (clr.Flavor == ClrFlavor.Desktop) { clrInfo = clr; break; } } } if (clrInfo == null) { throw new InvalidOperationException("No CLR runtime is present"); } ClrRuntime runtime; string dacFilePath = GetDacFile(clrInfo); try { runtime = clrInfo.CreateRuntime(dacFilePath); } catch (DllNotFoundException ex) { // This is a workaround for the Microsoft SDK docker images. Can fail when clrmd uses libdl.so // to create a symlink to and load the DAC module. if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { throw new DllNotFoundException("Problem initializing CLRMD. Try installing libc6-dev (apt-get install libc6-dev) to work around this problem.", ex); } else { throw; } } return(runtime); }
public async Task InvokeAsync(HttpContext context) { ClrInfo runtimeInfo = _dataTargetProvider.GetDataTarget().ClrVersions[0]; ClrRuntime runtime = runtimeInfo.CreateRuntime(); var content = TableBuilder.CreateDataTable("Threads", runtime.Threads.Select(f => new { ThreadId = TableColumn.Wrap(f.OSThreadId).Link($"{context.Request.PathBase.Value}/stacks?id={f.OSThreadId}"), GcMode = f.GcMode, Runtime = f.Runtime.ToString(), AppDomains = string.Join(",", f.Runtime.AppDomains.Select(a => a.Name)) })); await _next(context); await context.Response.WriteAsync(content); }
static void Main(string[] args) { if (!File.Exists(args[0])) { Console.WriteLine("Please provide path to memory dump"); return; } var tasksObjests = new HashSet <ulong>(); using (var dataTarget = DataTarget.LoadCrashDump(args[0])) { ClrInfo runtimeInfo = dataTarget.ClrVersions[0]; // just using the first runtime ClrRuntime runtime = runtimeInfo.CreateRuntime(); foreach (ulong obj in runtime.Heap.EnumerateObjectAddresses()) { ClrType type = runtime.Heap.GetObjectType(obj); if (type.Name.StartsWith(typeof(Task).FullName)) { var flagsValue = type.GetFieldByName("m_stateFlags")?.GetValue(obj); if (flagsValue != null && flagsValue is int stateFlags) { var status = GetTaskStatus(stateFlags); Console.WriteLine($"Found {type.Name}, state {status}, memory address {obj}"); tasksObjests.Add(obj); } } } Console.WriteLine("\nEnter memory address to explore GC roots or enter to end\n"); while (true) { if (ulong.TryParse(Console.ReadLine(), out var address) && tasksObjests.Contains(address)) { Console.WriteLine(); ShowMemoryRoots(runtime.Heap, address); } else { return; } } } }
static void Main(string[] args) { if (args.Length != 1) { Console.WriteLine("Usage: CLRHeapAnalyzer <dumpfile>"); return; } try { using (DataTarget dataTarget = DataTarget.LoadCrashDump(args[0])) { ClrInfo version = dataTarget.ClrVersions[0]; ClrRuntime runtime = version.CreateRuntime(); ClrHeap heap = runtime.GetHeap(); if (!heap.CanWalkHeap) { string err = "Error: Cannot walk the heap!"; Console.WriteLine(err); throw new Exception(err); } var stats = from o in heap.EnumerateObjects() let t = heap.GetObjectType(o) group o by t into g let size = g.Sum(o => (uint)g.Key.GetSize(o)) orderby size select new { Name = g.Key.Name, Size = size, Count = g.Count() }; foreach (var item in stats) { Console.WriteLine("{0,12:n0} {1,12:n0} {2}", item.Size, item.Count, item.Name); } } } catch (Exception e) { Console.WriteLine(e); } }