public void Execute(CommandExecutionContext context) { if (ExceptionAddress != 0) { var heap = context.Runtime.GetHeap(); var type = heap.GetObjectType(ExceptionAddress); if (type == null || !type.IsException) { context.WriteError("The specified address is not the address of an Exception-derived object."); return; } DisplayException(heap.GetExceptionObject(ExceptionAddress), context); } else { var thread = context.CurrentThread; if (thread == null) { context.WriteError("There is no current managed thread"); return; } if (thread.CurrentException == null) { context.WriteLine("There is no current managed exception on this thread"); return; } DisplayException(thread.CurrentException, context); } }
public void Execute(CommandExecutionContext context) { if (!InMemoryOnly) { if (context.TargetType == TargetType.LiveProcess) { context.WriteError( "Generating a persistent heap index for a live process is not recommended. " + "Use the --nofile switch to generate an in-memory index instead."); return; } if (String.IsNullOrEmpty(HeapIndexFileName)) { HeapIndexFileName = Path.ChangeExtension(context.DumpFile, ".heapindex"); context.WriteLine("Using an automatically generated heap index filename: '{0}'", HeapIndexFileName); } } if (InMemoryOnly && !String.IsNullOrEmpty(HeapIndexFileName)) { context.WriteError("The --nofile and -f options are incompatible."); return; } // If the index fails to build, clear it so that other commands know we don't have an index. context.HeapIndex = new HeapIndex(context); if (!context.HeapIndex.Build(ChunkSize, InMemoryOnly ? null : HeapIndexFileName, !EnumerateRootsFast)) context.HeapIndex = null; }
public void Execute(CommandExecutionContext context) { if (!InMemoryOnly) { if (context.TargetType == TargetType.LiveProcess) { context.WriteError( "Generating a persistent heap index for a live process is not recommended. " + "Use the --nofile switch to generate an in-memory index instead."); return; } if (String.IsNullOrEmpty(HeapIndexFileName)) { HeapIndexFileName = Path.ChangeExtension(context.DumpFile, ".heapindex"); context.WriteLine("Using an automatically generated heap index filename: '{0}'", HeapIndexFileName); } } if (InMemoryOnly && !String.IsNullOrEmpty(HeapIndexFileName)) { context.WriteError("The --nofile and -f options are incompatible."); return; } // If the index fails to build, clear it so that other commands know we don't have an index. context.HeapIndex = new HeapIndex(context); if (!context.HeapIndex.Build(ChunkSize, InMemoryOnly ? null : HeapIndexFileName, !EnumerateRootsFast)) { context.HeapIndex = null; } }
public void Execute(CommandExecutionContext context) { _context = context; _output = new PlainTextOutput(); if (!String.IsNullOrEmpty(AssemblyName)) { ClrModule module = context.Runtime.EnumerateModules().SingleOrDefault( m => Path.GetFileNameWithoutExtension(m.FileName).Equals( Path.GetFileNameWithoutExtension(AssemblyName), StringComparison.InvariantCultureIgnoreCase ) ); if (module == null) { context.WriteError("Could not find the assembly '{0}'.", AssemblyName); return; } if (!String.IsNullOrEmpty(TypeName)) { DecompileTypeFromModule(TypeName, module.FileName); } else { DecompileModule(module); } } else if (!String.IsNullOrEmpty(TypeName)) { ClrType type = context.Heap.GetTypeByName(TypeName); if (type == null) { context.WriteError( "Could not find the type '{0}' on the heap. Try specifying the assembly name.", TypeName); return; } if (!String.IsNullOrEmpty(MethodName)) { var methods = type.Methods.Where(m => m.Name == MethodName).ToArray(); if (methods.Length == 0) { context.WriteError("Could not find the method '{0}'.", MethodName); return; } DecompileMethods(methods); } else { DecompileType(type); } } else { context.WriteError("At least one of --assembly or --type must be specified."); } }
public void Execute(CommandExecutionContext context) { _context = context; _output = new PlainTextOutput(); if (!String.IsNullOrEmpty(AssemblyName)) { ClrModule module = context.Runtime.Modules.SingleOrDefault( m => Path.GetFileNameWithoutExtension(m.FileName).Equals( Path.GetFileNameWithoutExtension(AssemblyName), StringComparison.InvariantCultureIgnoreCase ) ); if (module == null) { context.WriteError("Could not find the assembly '{0}'.", AssemblyName); return; } if (!String.IsNullOrEmpty(TypeName)) { DecompileTypeFromModule(TypeName, module.FileName); } else { DecompileModule(module); } } else if (!String.IsNullOrEmpty(TypeName)) { ClrType type = context.Heap.GetTypeByName(TypeName); if (type == null) { context.WriteError( "Could not find the type '{0}' on the heap. Try specifying the assembly name.", TypeName); return; } if (!String.IsNullOrEmpty(MethodName)) { var methods = type.Methods.Where(m => m.Name == MethodName).ToArray(); if (methods.Length == 0) { context.WriteError("Could not find the method '{0}'.", MethodName); return; } DecompileMethods(methods); } else { DecompileType(type); } } else { context.WriteError("At least one of --assembly or --type must be specified."); } }
public void Execute(CommandExecutionContext context) { _context = context; if (!CommandHelpers.VerifyValidObjectAddress(context, ObjectAddress)) return; _heap = context.Heap; if (!_heap.CanWalkHeap) { context.WriteError("The heap is not in a walkable state."); return; } var type = _heap.GetObjectType(ObjectAddress); _visitedObjects = new ObjectSet(_heap); _targets[ObjectAddress] = new Node(ObjectAddress, type); FillRootDictionary(); foreach (var root in _roots) { if (_visitedRoots.Contains(root) || _visitedObjects.Contains(root.Object)) continue; Node path = TryFindPathToTarget(root); if (path != null) PrintOnePath(path); } }
public void Execute(CommandExecutionContext context) { if (!CommandHelpers.VerifyValidObjectAddress(context, ObjectAddress)) return; var type = context.Heap.GetObjectType(ObjectAddress); if (!type.IsArray) { context.WriteError("The object at the specified address is not an array."); return; } var size = type.GetSize(ObjectAddress); var length = type.GetArrayLength(ObjectAddress); context.WriteLine("Name: {0}", type.Name); context.WriteLine("Size: {0}(0x{1:x}) bytes", size, size); context.WriteLine("Array: Number of elements {0}, Type {1} {2}", length, type.ComponentType.Name, type.ComponentType.IsValueClass ? "(value type)" : "(reference type)"); for (int i = 0; i < length; ++i) { context.Write("[{0}] ", i); object value; if (type.ComponentType.IsValueClass) { value = type.GetArrayElementAddress(ObjectAddress, i); if (value != null) { context.WriteLink( String.Format("{0:x16}", value), String.Format("!do {0:x16} --type {1}", value, type.ComponentType.Name) ); } else { context.Write("<null>"); } } else { value = type.GetArrayElementValue(ObjectAddress, i); ulong elementAddr = type.GetArrayElementAddress(ObjectAddress, i); ulong elementRef; if (context.Runtime.ReadPointer(elementAddr, out elementRef)) { context.WriteLink( String.Format("{0:x16}", value ?? "<null>"), String.Format("!do {0:x16}", elementRef) ); } else { context.Write("{0:x16}", value ?? "<null>"); } } context.WriteLine(); } }
private void Bail(string format, params object[] args) { string errorMessage = String.Format(format, args); _context.WriteError(errorMessage); throw new AnalysisFailedException(errorMessage); }
public void Execute(CommandExecutionContext context) { if (!CommandHelpers.VerifyValidObjectAddress(context, ObjectAddress)) return; var type = context.Heap.GetObjectType(ObjectAddress); var dynamicObj = context.Heap.GetDynamicObject(ObjectAddress); context.WriteLine("Type: {0}", type.Name); if (type.IsArray || dynamicObj.IsList()) { int length = dynamicObj.GetLength(); context.WriteLine("Length: {0}", length); for (int i = 0; i < length; ++i) { context.WriteLine("[{0}] {1}", i, dynamicObj[i]); } } else if (dynamicObj.IsDictionary()) { context.WriteLine("Size: {0}", dynamicObj.GetLength()); context.WriteLine("{0,-40} {1,-40}", "Key", "Value"); foreach (var kvp in dynamicObj.GetDictionaryItems()) { context.WriteLine("{0,-40} {1,-40}", kvp.Item1, kvp.Item2); } } else { context.WriteError("The specified object is not an array, list, or dictionary. " + "These are the only collection types that are currently supported. For other " + "collections, try using the !hq command to inspect the object's contents."); return; } }
private void AttachToProcessByName() { string processName = _options.ProcessName; Process[] processes = Process.GetProcessesByName(processName); if (processes.Length == 0) { Bail("There are no processes matching the name '{0}'.", processName); } if (processes.Length > 1) { _context.WriteError("There is more than one process matching the name '{0}', use --pid to disambiguate.", processName); _context.WriteInfo("Matching process ids: {0}", String.Join(", ", processes.Select(p => p.Id).ToArray())); Bail(); } _target = new AnalysisTarget(processes[0].Id, _context, _options.ClrVersion); }
public void Execute(CommandExecutionContext context) { if (!context.Aliases.Remove(AliasName)) { context.WriteError("Unknown alias '{0}'", AliasName); return; } }
public static bool VerifyHasHeapIndex(CommandExecutionContext context) { if (context.HeapIndex == null) { context.WriteError("This command requires a heap index. Build one with !bhi or load one with !lhi."); return(false); } return(true); }
public void Execute(CommandExecutionContext context) { if (context.Aliases.ContainsKey(AliasName)) { context.WriteError("The specified alias already exists. Clear it first with .rmalias."); return; } context.Aliases.Add(AliasName, AliasCommand); }
public static bool VerifyHasHeapIndex(CommandExecutionContext context) { if (context.HeapIndex == null) { context.WriteError("This command requires a heap index. Build one with !bhi or load one with !lhi."); return false; } return true; }
public static bool VerifyValidObjectAddress( CommandExecutionContext context, ulong objectAddress) { var heap = context.Runtime.GetHeap(); var type = heap.GetObjectType(objectAddress); if (type == null || String.IsNullOrEmpty(type.Name)) { context.WriteError("The specified address does not point to a valid object."); return(false); } if (type.IsFree) { context.WriteError("The specified address points to a free object."); return(false); } return(true); }
public static bool VerifyValidObjectAddress( CommandExecutionContext context, ulong objectAddress) { var heap = context.Runtime.GetHeap(); var type = heap.GetObjectType(objectAddress); if (type == null || String.IsNullOrEmpty(type.Name)) { context.WriteError("The specified address does not point to a valid object."); return false; } if (type.IsFree) { context.WriteError("The specified address points to a free object."); return false; } return true; }
public static void ExecuteDbgEngCommand(this DataTarget target, string command, CommandExecutionContext context) { IDebugControl6 control = (IDebugControl6)target.DebuggerInterface; int hr = control.ExecuteWide( DEBUG_OUTCTL.THIS_CLIENT, command, DEBUG_EXECUTE.DEFAULT); if (HR.Failed(hr)) { context.WriteError("Command execution failed with hr = {0:x8}", hr); } }
public void Execute(CommandExecutionContext context) { if (HelperIndex < 0 || HelperIndex >= context.Defines.Count) { context.WriteError( "There is no helper method at index {0} defined. Use .listdefines to get the indexes.", HelperIndex); return; } context.Defines.RemoveAt(HelperIndex); }
public void Execute(CommandExecutionContext context) { if (context.Runtime.Threads.Any(t => t.ManagedThreadId == ManagedThreadId)) { context.CurrentManagedThreadId = ManagedThreadId; } else { context.WriteError("No thread has the managed thread id {0}", ManagedThreadId); } }
public void Execute(CommandExecutionContext context) { _context = context; var thread = context.CurrentThread; if (thread == null) { context.WriteError("There is no current managed thread"); return; } thread.WriteCurrentStackTraceToContext(context, DisplayArgumentsAndLocals); }
public void Execute(CommandExecutionContext context) { AppDomainSetup setupInfo = new AppDomainSetup(); setupInfo.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; setupInfo.PrivateBinPath = "bin"; AppDomain appDomain = AppDomain.CreateDomain("RunQueryAppDomain", null, setupInfo); string compilationOutputDirectory = null; object[] arguments; if (context.ProcessId != 0) { arguments = new object[] { context.ProcessId, context.DacLocation, context.Printer }; } else { arguments = new object[] { context.DumpFile, context.DacLocation, context.Printer }; } using (RunInSeparateAppDomain runner = (RunInSeparateAppDomain)appDomain.CreateInstanceAndUnwrap( typeof(RunInSeparateAppDomain).Assembly.FullName, typeof(RunInSeparateAppDomain).FullName, false, System.Reflection.BindingFlags.CreateInstance, null, arguments, null, null ) ) { try { compilationOutputDirectory = runner.RunQuery( OutputFormat.ToString(), Query, context.Defines); } catch (Exception ex) { // Catching everything here because the input is user-controlled, so we can have // compilation errors, dynamic binder errors, and a variety of other things I haven't // even thought of yet. context.WriteError(ex.Message); } } AppDomain.Unload(appDomain); if (compilationOutputDirectory != null) { Directory.Delete(compilationOutputDirectory, recursive: true); } }
public void Execute(CommandExecutionContext context) { if (String.IsNullOrEmpty(HeapIndexFileName)) { if (context.TargetType != TargetType.DumpFile) { context.WriteError("You must specify the heap index's location."); return; } HeapIndexFileName = Path.ChangeExtension(context.DumpFile, ".heapindex"); context.WriteLine("Using automatically generated heap index filename: '{0}'", HeapIndexFileName); } if (!File.Exists(HeapIndexFileName)) { context.WriteError("The heap index file '{0}' does not exist.", HeapIndexFileName); return; } context.HeapIndex = new HeapIndex(context); context.HeapIndex.Load(HeapIndexFileName); context.WriteLine("Loaded heap index from file '{0}'", HeapIndexFileName); }
public void Execute(CommandExecutionContext context) { if (Disable) { context.Printer.RowsPerPage = 0; return; } if (RowsPerPage == 0) { context.WriteError("Can't have 0 rows per page. Use --disable to disable paging altogether."); return; } context.Printer.RowsPerPage = RowsPerPage; }
public void Execute(CommandExecutionContext context) { string aliasCommand; if (!context.Aliases.TryGetValue(AliasName, out aliasCommand)) { context.WriteError("Unknown alias '{0}'", AliasName); return; } int index = 1; foreach (var paramValue in AliasParameters.Split(' ')) { aliasCommand = aliasCommand.Replace("$" + index, paramValue); } context.WriteInfo("Alias '{0}' expanded to '{1}'", AliasName, aliasCommand); context.ExecuteCommand(aliasCommand); }
public void Execute(CommandExecutionContext context) { AppDomainSetup setupInfo = new AppDomainSetup(); setupInfo.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; setupInfo.PrivateBinPath = "bin"; AppDomain appDomain = AppDomain.CreateDomain("RunQueryAppDomain", null, setupInfo); string compilationOutputDirectory = null; object[] arguments; if (context.ProcessId != 0) { arguments = new object[] { context.ProcessId, context.ClrVersionIndex, context.DacLocation, context.Printer }; } else { arguments = new object[] { context.DumpFile, context.ClrVersionIndex, context.DacLocation, context.Printer }; } using (RunInSeparateAppDomain runner = (RunInSeparateAppDomain)appDomain.CreateInstanceAndUnwrap( typeof(RunInSeparateAppDomain).Assembly.FullName, typeof(RunInSeparateAppDomain).FullName, false, System.Reflection.BindingFlags.CreateInstance, null, arguments, null, null ) ) { try { compilationOutputDirectory = runner.RunQuery( OutputFormat.ToString(), Query, context.Defines); } catch (Exception ex) { // Catching everything here because the input is user-controlled, so we can have // compilation errors, dynamic binder errors, and a variety of other things I haven't // even thought of yet. context.WriteError(ex.Message); } } AppDomain.Unload(appDomain); if (compilationOutputDirectory != null) { Directory.Delete(compilationOutputDirectory, recursive: true); } }
public bool Build(int chunkSize, string indexFileName, bool enumerateAllRoots) { if (chunkSize < 256 || chunkSize > 1048576 || chunkSize % 16 != 0) { _context.WriteError("Chunk size must be between 256 bytes and 1MB, and must be a multiple of 16."); return(false); } _chunkSize = chunkSize; _staticRootsEnumerated = enumerateAllRoots; Measure(() => { _allRoots = (from root in _heap.EnumerateRoots(enumerateStatics: enumerateAllRoots) select new SimplifiedRoot(root)).ToList(); }, "Enumerating roots"); // Build an index of N-byte chunks in all heap segments. The index is from chunk-id (int?) to // the first non-free object in the chunk (not to start of the chunk, which could be in the middle // of an object). If a chunk is completely empty or doesn't contain the start of any object, it // doesn't have an id. Measure(BuildChunks, "Building chunks"); // Traverse all object relationships on the heap from roots. For each chunk, specify which other // chunks contain references to objects in that chunk. When traversing this information, we need to // keep in mind that roots can also contain references to objects in the chunk -- we don't store this // information again because it's very easy to obtain by enumerating the roots. This decision can be // changed if root enumeration turns out to be slow when there are many roots. // Note that only live objects are being enumerated. For dead objects, it's not interesting to ask who // has a reference to the object -- because the referencing object is also dead. Measure(BuildChunkIndex, "Building chunk index"); DisplayStatistics(); if (!String.IsNullOrEmpty(indexFileName)) { Measure(() => Save(indexFileName), "Saving index to disk"); } else { _context.WriteWarning("You did not specify a file name, so the index will be stored only in memory. " + "If you plan to perform further analysis in another session, it is recommended that you store " + "the index to disk and later load it using the !lhi command."); } return(true); }
public void Execute(CommandExecutionContext context) { _context = context; if (SpecificThreadId != 0) { var thread = _context.Runtime.Threads.SingleOrDefault(t => t.ManagedThreadId == SpecificThreadId); if (thread == null) { _context.WriteError("There is no managed thread with the id '{0}'.", SpecificThreadId); return; } DisplayChainForThread(thread); } else { _context.Runtime.Threads.ForEach(DisplayChainForThread); } }
public void Execute(CommandExecutionContext context) { _context = context; ClrMethod method = context.Runtime.GetMethodByAddress(InstructionPointer); if (method == null) { context.WriteError("There is no managed method at the address {0:x16}.", InstructionPointer); return; } _sourceFileCache = new Dictionary<string, string[]>(); using (var target = context.CreateTemporaryDbgEngTarget()) { _control = (IDebugControl)target.DebuggerInterface; DisassembleMethod(method); } }
public void Execute(CommandExecutionContext context) { _context = context; ClrMethod method = context.Runtime.GetMethodByAddress(InstructionPointer); if (method == null) { context.WriteError("There is no managed method at the address {0:x16}.", InstructionPointer); return; } _sourceFileCache = new Dictionary <string, string[]>(); using (var target = context.CreateTemporaryDbgEngTarget()) { _control = (IDebugControl)target.DebuggerInterface; DisassembleMethod(method); } }
public void Execute(CommandExecutionContext context) { byte[] buffer = new byte[Columns]; for (int remaining = Length; remaining > 0; remaining -= Columns, Address += (uint)Columns) { int read = 0; if (!context.Runtime.ReadMemory(Address, buffer, Math.Min(remaining, Columns), out read)) { context.WriteError("Error reading memory at {0:x16}, could only read {1} bytes while {2} requested", Address, read, Columns); return; } string bytes = ""; string chars = ""; for (int col = 0; col < read; ++col) { bytes += String.Format("{0:x2} ", buffer[col]); chars += (buffer[col] >= 32 && buffer[col] <= 126) ? (char)buffer[col] : '.'; } context.WriteLine("{0:x16} {1} {2}", Address, bytes, chars); } }
public void Execute(CommandExecutionContext context) { if (!CommandHelpers.VerifyValidObjectAddress(context, ObjectAddress)) { return; } var type = context.Heap.GetObjectType(ObjectAddress); var dynamicObj = context.Heap.GetDynamicObject(ObjectAddress); context.WriteLine("Type: {0}", type.Name); if (type.IsArray || dynamicObj.IsList()) { int length = dynamicObj.GetLength(); context.WriteLine("Length: {0}", length); for (int i = 0; i < length; ++i) { context.WriteLine("[{0}] {1}", i, dynamicObj[i]); } } else if (dynamicObj.IsDictionary()) { context.WriteLine("Size: {0}", dynamicObj.GetLength()); context.WriteLine("{0,-40} {1,-40}", "Key", "Value"); foreach (var kvp in dynamicObj.GetDictionaryItems()) { context.WriteLine("{0,-40} {1,-40}", kvp.Item1, kvp.Item2); } } else { context.WriteError("The specified object is not an array, list, or dictionary. " + "These are the only collection types that are currently supported. For other " + "collections, try using the !hq command to inspect the object's contents."); return; } }
public void Execute(CommandExecutionContext context) { _context = context; if (!CommandHelpers.VerifyValidObjectAddress(context, ObjectAddress)) { return; } _heap = context.Heap; if (!_heap.CanWalkHeap) { context.WriteError("The heap is not in a walkable state."); return; } var type = _heap.GetObjectType(ObjectAddress); _visitedObjects = new ObjectSet(_heap); _targets[ObjectAddress] = new Node(ObjectAddress, type); FillRootDictionary(); foreach (var root in _roots) { if (_visitedRoots.Contains(root) || _visitedObjects.Contains(root.Object)) { continue; } Node path = TryFindPathToTarget(root); if (path != null) { PrintOnePath(path); } } }
public int Output(DEBUG_OUTPUT mask, string text) { switch (mask) { case DEBUG_OUTPUT.ERROR: _context.WriteError(text); break; case DEBUG_OUTPUT.EXTENSION_WARNING: case DEBUG_OUTPUT.WARNING: _context.WriteWarning(text); break; case DEBUG_OUTPUT.SYMBOLS: _context.WriteInfo(text); break; default: _context.Write(text); break; } return(0); }
public void Execute(CommandExecutionContext context) { _context = context; ClrType type; if (!String.IsNullOrEmpty(TypeName)) { type = context.Heap.GetTypeByName(TypeName); if (type == null) { context.WriteError("There is no type named '{0}'.", TypeName); return; } } else { type = context.Heap.GetObjectType(ObjectAddress); if (type == null || String.IsNullOrEmpty(type.Name)) { context.WriteError("The specified address is not an object."); return; } } ulong mt = 0; if (type.IsObjectReference && !context.Runtime.ReadPointer(ObjectAddress, out mt)) { context.WriteWarning("Unable to retrieve MT for object."); } var size = type.GetSize(ObjectAddress); context.Write("Name: {0}", type.Name); var dynamicObj = context.Heap.GetDynamicObject(ObjectAddress); if (type.IsArray || dynamicObj.IsList() || dynamicObj.IsDictionary()) { context.WriteLink(" <display elements>", String.Format("!dumpcollection {0:x16}", ObjectAddress)); } context.WriteLine(); if (mt != 0) { context.WriteLine("MT: {0:x16}", mt); } context.WriteLine("Size: {0}(0x{1:x}) bytes", size, size); if (type.IsArray) { context.WriteLine("Array: size {0}, element type {1}", type.GetArrayLength(ObjectAddress), type.ArrayComponentType != null ? type.ArrayComponentType.Name : "<unknown>"); } context.WriteLine("Assembly: {0}", type.Module.FileName); if (type.HasSimpleValue) { context.WriteLine("Value: {0}", type.GetValue(ObjectAddress)); } if (!NoFields && type.Fields.Count > 0) { context.WriteLine("Fields:"); context.WriteLine("{0,-8} {1,-20} {2,-3} {3,-10} {4,-20} {5}", "Offset", "Type", "VT", "Attr", "Value", "Name"); foreach (var field in type.Fields) { DisplayFieldRecursively(field, new InstanceFieldValueForDisplayRetriever(ObjectAddress), field.Offset, depth: type.IsValueClass ? 1 : 0); } foreach (var field in type.ThreadStaticFields) { context.WriteLine("{0,-8:x} {1,-20} {2,-3} {3,-10} {4,-20:x16} {5}", field.Offset, field.GetFieldTypeNameTrimmed(), (field.IsPrimitive() || field.IsValueClass()) ? 1 : 0, "shared", "thrstatic", field.Name); foreach (var appDomain in context.Runtime.AppDomains) { foreach (var thread in context.Runtime.Threads) { DisplayFieldRecursively(field, new ThreadStaticFieldValueForDisplayRetriever(appDomain, thread), field.Offset); } } } foreach (var field in type.StaticFields) { context.WriteLine("{0,-8:x} {1,-20} {2,-3} {3,-10} {4,-20:x16} {5}", field.Offset, field.GetFieldTypeNameTrimmed(), (field.IsPrimitive() || field.IsValueClass()) ? 1 : 0, "shared", "static", field.Name); foreach (var appDomain in context.Runtime.AppDomains) { DisplayFieldRecursively(field, new StaticFieldValueForDisplayRetriever(appDomain), field.Offset); } } } }
public void Execute(CommandExecutionContext context) { if (!String.IsNullOrEmpty(TypeRegex)) { try { new Regex(TypeRegex); } catch (ArgumentException) { context.WriteError("The regular expression specified for --type is not valid; did you forget to escape regex characters?"); return; } } _heap = context.Runtime.GetHeap(); if (!_heap.CanWalkHeap) { context.WriteError("The heap is not in a walkable state."); return; } var typeInfos = new Dictionary <ulong, TypeInfo>(); // MT to TypeInfo long totalObjectCount = 0; if (!StatisticsOnly) { context.WriteLine("{0,-20} {1,-20} {2}", "MT", "Address", "Size"); } foreach (var obj in _heap.EnumerateObjects()) { ulong mt = 0; context.Runtime.ReadPointer(obj, out mt); if (!FilterObject(obj, mt)) { continue; } var type = _heap.GetObjectType(obj); if (type == null || String.IsNullOrEmpty(type.Name)) { continue; } var size = type.GetSize(obj); if (!StatisticsOnly) { context.WriteLine("{0,-20:x16} {1,-20:x16} {2,-10}", mt, obj, size); } if (typeInfos.ContainsKey(mt)) { var current = typeInfos[mt]; current.Count += 1; current.Size += size; typeInfos[mt] = current; } else { var objType = _heap.GetObjectType(obj); var objTypeName = objType != null ? objType.Name : "<no name>"; typeInfos.Add(mt, new TypeInfo { Size = size, Count = 1, TypeName = objTypeName }); } ++totalObjectCount; } context.WriteLine("Statistics:"); context.WriteLine("{0,-20} {1,-10} {2,-10} {3}", "MT", "Count", "TotalSize", "Class Name"); foreach (var kvp in (from e in typeInfos orderby e.Value.Size ascending select e)) { context.WriteLine("{0,-20:x16} {1,-10} {2,-10} {3}", kvp.Key, kvp.Value.Count, kvp.Value.Size, kvp.Value.TypeName); } context.WriteLine("Total {0} objects", totalObjectCount); }
public void Execute(CommandExecutionContext context) { if (!String.IsNullOrEmpty(TypeRegex)) { try { new Regex(TypeRegex); } catch (ArgumentException) { context.WriteError("The regular expression specified for --type is not valid; did you forget to escape regex characters?"); return; } } _heap = context.Runtime.GetHeap(); if (!_heap.CanWalkHeap) { context.WriteError("The heap is not in a walkable state."); return; } var typeInfos = new Dictionary<ulong, TypeInfo>(); // MT to TypeInfo long totalObjectCount = 0; if (!StatisticsOnly) { context.WriteLine("{0,-20} {1,-20} {2}", "MT", "Address", "Size"); } foreach (var obj in _heap.EnumerateObjectAddresses()) { ulong mt = 0; context.Runtime.ReadPointer(obj, out mt); if (!FilterObject(obj, mt)) continue; var type = _heap.GetObjectType(obj); if (type == null || String.IsNullOrEmpty(type.Name)) continue; var size = type.GetSize(obj); if (!StatisticsOnly) { context.WriteLine("{0,-20:x16} {1,-20:x16} {2,-10}", mt, obj, size); } if (typeInfos.ContainsKey(mt)) { var current = typeInfos[mt]; current.Count += 1; current.Size += size; typeInfos[mt] = current; } else { var objType = _heap.GetObjectType(obj); var objTypeName = objType != null ? objType.Name : "<no name>"; typeInfos.Add(mt, new TypeInfo { Size = size, Count = 1, TypeName = objTypeName }); } ++totalObjectCount; } context.WriteLine("Statistics:"); context.WriteLine("{0,-20} {1,-10} {2,-10} {3}", "MT", "Count", "TotalSize", "Class Name"); foreach (var kvp in (from e in typeInfos orderby e.Value.Size ascending select e)) { context.WriteLine("{0,-20:x16} {1,-10} {2,-10} {3}", kvp.Key, kvp.Value.Count, kvp.Value.Size, kvp.Value.TypeName); } context.WriteLine("Total {0} objects", totalObjectCount); }
public void Execute(CommandExecutionContext context) { if (!CommandHelpers.VerifyValidObjectAddress(context, ObjectAddress)) { return; } var type = context.Heap.GetObjectType(ObjectAddress); if (!type.IsArray) { context.WriteError("The object at the specified address is not an array."); return; } var size = type.GetSize(ObjectAddress); var length = type.GetArrayLength(ObjectAddress); context.WriteLine("Name: {0}", type.Name); context.WriteLine("Size: {0}(0x{1:x}) bytes", size, size); context.WriteLine("Array: Number of elements {0}, Type {1} {2}", length, type.ArrayComponentType.Name, type.ArrayComponentType.IsValueClass ? "(value type)" : "(reference type)"); for (int i = 0; i < length; ++i) { context.Write("[{0}] ", i); object value; if (type.ArrayComponentType.IsValueClass) { value = type.GetArrayElementAddress(ObjectAddress, i); if (value != null) { context.WriteLink( String.Format("{0:x16}", value), String.Format("!do {0:x16} --type {1}", value, type.ArrayComponentType.Name) ); } else { context.Write("<null>"); } } else { value = type.GetArrayElementValue(ObjectAddress, i); ulong elementAddr = type.GetArrayElementAddress(ObjectAddress, i); ulong elementRef; if (context.Runtime.ReadPointer(elementAddr, out elementRef)) { context.WriteLink( String.Format("{0:x16}", value ?? "<null>"), String.Format("!do {0:x16}", elementRef) ); } else { context.Write("{0:x16}", value ?? "<null>"); } } context.WriteLine(); } }
public static void ExecuteDbgEngCommand(this DataTarget target, string command, CommandExecutionContext context) { IDebugControl6 control = (IDebugControl6)target.DebuggerInterface; int hr = control.ExecuteWide( DEBUG_OUTCTL.THIS_CLIENT, command, DEBUG_EXECUTE.DEFAULT); if (HR.Failed(hr)) context.WriteError("Command execution failed with hr = {0:x8}", hr); }