public void Execute(CommandExecutionContext context) { IEnumerable <ClrAppDomain> appDomains = context.Runtime.AppDomains; if (Id != 0) { appDomains = appDomains.Where(ad => ad.Id == Id); } context.WriteLine("{0,-4} {1,-40} {2,-10} {3}", "Id", "Name", "# Modules", "Application Base"); foreach (var appDomain in appDomains) { context.WriteLine("{0,-4} {1,-40} {2,-10} {3}", appDomain.Id, appDomain.Name.TrimEndToLength(40), appDomain.Modules.Count, appDomain.ApplicationBase); if (Id != 0) { foreach (var module in appDomain.Modules) { context.WriteLine(" {0}", module.FileName); } } } }
public void Execute(CommandExecutionContext context) { context.EnterDbgEngNativeMode(); // In case the user is going to use sos/sosex, make sure they have // the appropriate DAC location configured. context.WriteLine("Loading DAC from " + context.DacLocation); context.NativeDbgEngTarget.ExecuteDbgEngCommand( ".cordll -ve -sd -lp " + Path.GetDirectoryName(context.DacLocation), context); // SOS hasn't necessarily been loaded at this point; try to load it // from the symbol server and then issue the appropriate .load command // so that the user can have it immediately available. string sosLocation = context.Runtime.TryDownloadSos(); if (sosLocation == null) { context.WriteWarningLine( "Unable to load SOS automatically from symbol server, " + "try to find and .load it manually if needed."); } else { context.WriteLine("Loading SOS from " + sosLocation); context.NativeDbgEngTarget.ExecuteDbgEngCommand( ".load " + sosLocation, context); } }
public void Execute(CommandExecutionContext context) { if (!CommandHelpers.VerifyHasHeapIndex(context)) return; if (!CommandHelpers.VerifyValidObjectAddress(context, ObjectAddress)) return; int pathsDisplayed = 0; foreach (var path in context.HeapIndex.FindPaths(ObjectAddress, MaxResults, MaxLocalRoots, MaxDepth, RunInParallel)) { context.WriteLine("{0:x16} -> {1:x16} {2}", path.Root.Address, path.Root.Object, path.Root.DisplayText); foreach (var obj in path.Chain) { string objHex = String.Format("{0:x16}", obj); context.Write(" -> "); context.WriteLink(objHex, "!do " + objHex); context.WriteLine(" {0}", context.Heap.GetObjectType(obj).Name); } context.WriteLine(); ++pathsDisplayed; } context.WriteLine("Total paths displayed: {0}", pathsDisplayed); if (pathsDisplayed == 0) { context.WriteLine("Number of paths may be affected by maximum depth setting. " + "If you are not seeing enough results, consider increasing --maxDepth."); } }
public void Execute(CommandExecutionContext context) { context.EnterDbgEngNativeMode(); // In case the user is going to use sos/sosex, make sure they have // the appropriate DAC location configured. context.WriteLine("Loading DAC from " + context.DacLocation); context.NativeDbgEngTarget.ExecuteDbgEngCommand( ".cordll -ve -sd -lp " + Path.GetDirectoryName(context.DacLocation), context); // SOS hasn't necessarily been loaded at this point; try to load it // from the symbol server and then issue the appropriate .load command // so that the user can have it immediately available. string sosLocation = context.Runtime.TryDownloadSos(); if (sosLocation == null) { context.WriteWarning( "Unable to load SOS automatically from symbol server, " + "try to find and .load it manually if needed."); } else { context.WriteLine("Loading SOS from " + sosLocation); context.NativeDbgEngTarget.ExecuteDbgEngCommand( ".load " + sosLocation, context); } }
public void Execute(CommandExecutionContext context) { if (!CommandHelpers.VerifyHasHeapIndex(context)) { return; } if (!CommandHelpers.VerifyValidObjectAddress(context, ObjectAddress)) { return; } int pathsDisplayed = 0; foreach (var path in context.HeapIndex.FindPaths(ObjectAddress, MaxResults, MaxLocalRoots, MaxDepth, RunInParallel)) { context.WriteLine("{0:x16} -> {1:x16} {2}", path.Root.Address, path.Root.Object, path.Root.DisplayText); foreach (var obj in path.Chain) { string objHex = String.Format("{0:x16}", obj); context.Write(" -> "); context.WriteLink(objHex, "!do " + objHex); context.WriteLine(" {0}", context.Heap.GetObjectType(obj).Name); } context.WriteLine(); ++pathsDisplayed; } context.WriteLine("Total paths displayed: {0}", pathsDisplayed); if (pathsDisplayed == 0) { context.WriteLine("Number of paths may be affected by maximum depth setting. " + "If you are not seeing enough results, consider increasing --maxDepth."); } }
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(); } }
public void Execute(CommandExecutionContext context) { context.WriteLine("Hex: {0:x16}", Value); context.WriteLine("Decimal: {0}", Value); context.WriteLine("Binary: {0}", Convert.ToString((long)Value, 2).PadLeft(16, '0')); context.WriteLine("Float: {0}", BitConverter.ToSingle(BitConverter.GetBytes(Value), 0)); context.WriteLine("Double: {0}", BitConverter.Int64BitsToDouble((long)Value)); }
public void Execute(CommandExecutionContext context) { context.WriteLine("{0,-20} {1,-10} {2,-8} {3,-20} {4,-20}", "Address", "Type", "Locked", "Owner(s)", "Waiter(s)"); foreach (var blockingObject in context.Runtime.GetHeap().EnumerateBlockingObjects()) { context.Write("{0,-20:x16} {1,-10} {2,-8} {3,-20} {4,-20}", blockingObject.Object, blockingObject.Reason, blockingObject.Taken ? 1 : 0, String.Join(", ", from thread in blockingObject.Owners where thread != null select thread.ManagedThreadId), String.Join(", ", from thread in blockingObject.Waiters where thread != null select thread.ManagedThreadId)); context.WriteLink("", String.Format("!do {0:x16}", blockingObject.Object)); context.WriteLine(); } }
public void Execute(CommandExecutionContext context) { if (context.Defines.Count == 0) { context.WriteLine("You do not have any helper methods defined. Use .define to define some."); return; } context.WriteLine("{0,-6} {1}", "#", "Body"); for (int i = 0; i < context.Defines.Count; ++i) { context.WriteLine("{0,-6} {1}", i, context.Defines[i]); } }
private void ProcessStacks(IEnumerable <ThreadAndStack> stacks, int depth = 0) { if (depth >= Depth) { return; } var grouping = from stack in stacks where stack.Stack.Any() group stack by stack.Stack.First() into g orderby g.Count() descending select g; if (grouping.Count() == 1) { var stackGroup = grouping.First(); _context.WriteLine("{0}| {1}", new String(' ', depth * 2), stackGroup.Key); ProcessStacks(TrimOne(stackGroup), depth); } else { foreach (var stackGroup in grouping) { _context.Write("{0}+ {1} ", new String(' ', depth * 2), stackGroup.Key); if (!NoThreadDetails) { foreach (var ts in stackGroup) { if (ts.ManagedThreadId != 0) { _context.WriteLink( String.Format("M{0}", ts.ManagedThreadId), String.Format("~ {0}; !clrstack", ts.ManagedThreadId) ); } else { _context.WriteLink( String.Format("OS{0}", ts.OSThreadId), String.Format("!mk {0}", ts.OSThreadId) ); } _context.Write(" "); } } _context.WriteLine(); ProcessStacks(TrimOne(stackGroup), depth + 1); } } }
public void Execute(CommandExecutionContext context) { if (context.Aliases.Count == 0) { context.WriteLine("There are no aliases. Use .newalias to define some."); return; } context.WriteLine("{0,-20} {1}", "Name", "Command"); foreach (var aliasAndCommand in context.Aliases) { context.WriteLine("{0,-20} {1}", aliasAndCommand.Key, aliasAndCommand.Value); } }
public void Execute(CommandExecutionContext context) { if (!CommandHelpers.VerifyValidObjectAddress(context, ObjectAddress)) return; IEnumerable<Tuple<ulong, ClrType>> subgraph; if (Flat) { subgraph = context.Heap.FlatSubgraphOf(ObjectAddress); } else { subgraph = context.Heap.SubgraphOf(ObjectAddress); } ulong count = 0, size = 0; foreach (var objAndType in subgraph) { ++count; size += objAndType.Item2.GetSize(objAndType.Item1); } context.WriteLine("{0:x16} graph size is {1} objects, {2} bytes ({3})", ObjectAddress, count, size, size.ToMemoryUnits()); }
public void Execute(CommandExecutionContext context) { if (!InMemoryOnly) { if (context.TargetType == TargetType.LiveProcess) { context.WriteErrorLine( "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.WriteErrorLine("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.WriteLine("{0,-20} {1,-20} {2}", "Address", "Object", "Type"); foreach (var localRoot in context.CurrentThread.EnumerateStackObjects()) { var type = context.Heap.GetObjectType(localRoot.Object); context.Write("{0,-20:x16} {1,-20:x16} {2} ", localRoot.Address, localRoot.Object, type == null ? "" : type.Name); if (type != null && !type.IsFree) { context.WriteLink("", String.Format("!do {0:x16}", localRoot.Object)); } context.WriteLine(); } }
private void DisplayFieldRecursively <TField>(TField field, IFieldValueForDisplayRetriever <TField> retriever, int offset, string baseName = "", int depth = 0) where TField : ClrField { bool inner = depth > 0; var address = retriever.GetFieldAddress(field, inner); _context.Write(retriever.GetDisplayString(field, offset, baseName, inner)); if (field.IsObjectReferenceNotString()) { _context.WriteLink("", String.Format("!do {0}", retriever.GetFieldValue(field, inner))); } if (NoRecurse && field.ElementType == ClrElementType.Struct) { _context.WriteLink("", String.Format("!do {0:x16} --type {1}", address, field.Type.Name)); } _context.WriteLine(); if (!NoRecurse && field.ElementType == ClrElementType.Struct) { foreach (var innerField in field.Type.Fields) { var innerRetriever = new InstanceFieldValueForDisplayRetriever(address); DisplayFieldRecursively(innerField, innerRetriever, offset + innerField.Offset, baseName + field.Name + ".", depth + 1); } } }
public void Execute(CommandExecutionContext context) { if (!CommandHelpers.VerifyValidObjectAddress(context, ObjectAddress)) { return; } IEnumerable <Tuple <ulong, ClrType> > subgraph; if (Flat) { subgraph = context.Heap.FlatSubgraphOf(ObjectAddress); } else { subgraph = context.Heap.SubgraphOf(ObjectAddress); } ulong count = 0, size = 0; foreach (var objAndType in subgraph) { ++count; size += objAndType.Item2.GetSize(objAndType.Item1); } context.WriteLine("{0:x16} graph size is {1} objects, {2} bytes ({3})", ObjectAddress, count, size, size.ToMemoryUnits()); }
public void Execute(CommandExecutionContext context) { if (ExceptionAddress != 0) { var heap = context.Runtime.GetHeap(); var type = heap.GetObjectType(ExceptionAddress); if (type == null || !type.IsException) { context.WriteErrorLine("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.WriteErrorLine("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) { _context = context; if (!DisplayVirtualMemoryRanges && !DisplayVirtualMemoryStatistics && !DisplayManagedHeapStatistics && !DisplayManagedHeapFragmentation) { _context.WriteLine("No memory information requested. Use one of the " + "command switches, or look at the help: 'help !memstats'"); } if (DisplayVirtualMemoryStatistics) { VirtualMemoryStatistics(); } if (DisplayVirtualMemoryRanges) { VirtualMemoryRanges(); } if (DisplayManagedHeapStatistics) { ManagedHeapStatistics(); } if (DisplayManagedHeapFragmentation) { ManagedHeapFragmentation(); } }
public void Execute(CommandExecutionContext context) { if (!InMemoryOnly) { if (context.TargetType == TargetType.LiveProcess) { context.WriteErrorLine( "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.WriteErrorLine("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) { var writer = new DumpWriter.DumpWriter( Verbose ? new PrinterTextWriter(context.Printer) : null ); // TODO Try to make the string shared between here and the DumpNative class in CLRMD writer.Dump(context.ProcessId, DumpType, FileName, "DumpWriter dump: has heap"); context.WriteLine("Resulting dump size: {0:N0} bytes", new FileInfo(FileName).Length); }
public void Execute(CommandExecutionContext context) { if (context.IsInDbgEngNativeMode) { context.ExitDbgEngNativeMode(); context.WriteLine("Exited DbgEng mode; you are now back in msos."); } else { context.ShouldQuit = true; } }
private void DisplayChainForThreadAux(ClrThread thread, int depth, HashSet <int> visitedThreadIds) { _context.WriteLink( String.Format("{0}+ Thread {1}", new string(' ', depth * 2), thread.ManagedThreadId), String.Format("~ {0}; !clrstack", thread.ManagedThreadId)); _context.WriteLine(); if (visitedThreadIds.Contains(thread.ManagedThreadId)) { _context.WriteLine("{0}*** DEADLOCK!", new string(' ', depth * 2)); return; } visitedThreadIds.Add(thread.ManagedThreadId); foreach (var blockingObject in thread.BlockingObjects) { _context.Write("{0}| {1} ", new string(' ', (depth + 1) * 2), blockingObject.Reason); var type = _context.Heap.GetObjectType(blockingObject.Object); if (type != null && !String.IsNullOrEmpty(type.Name)) { _context.WriteLink( String.Format("{0:x16} {1}", blockingObject.Object, type.Name), String.Format("!do {0:x16}", blockingObject.Object)); } else { _context.Write("{0:x16}", blockingObject.Object); } _context.WriteLine(); foreach (var owner in blockingObject.Owners) { if (owner == null) // ClrMD sometimes reports this nonsense { continue; } DisplayChainForThreadAux(owner, depth + 2, visitedThreadIds); } } }
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.WriteErrorLine("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 (IncludeNativeThreads) { using (var target = context.CreateTemporaryDbgEngTarget()) { var tracer = new UnifiedStackTraces(target.DebuggerInterface, context); context.WriteLine("Stack tree for {0} threads:", tracer.NumThreads); var allStacks = from thread in tracer.Threads let frames = from frame in tracer.GetStackTrace(thread.Index) where frame.Type != UnifiedStackFrameType.Special select frame.DisplayString select new ThreadAndStack { ManagedThreadId = thread.IsManagedThread ? thread.ManagedThread.ManagedThreadId : 0, OSThreadId = thread.OSThreadId, Stack = frames.Reverse() }; ProcessStacks(allStacks); } } else { context.WriteLine("Stack tree for {0} threads:", context.Runtime.Threads.Count); var allStacks = from thread in context.Runtime.Threads let frames = from frame in thread.StackTrace where frame.Kind == ClrStackFrameType.ManagedMethod select frame.DisplayString select new ThreadAndStack { ManagedThreadId = thread.ManagedThreadId, Stack = frames.Reverse() }; ProcessStacks(allStacks); } }
private void Save(string indexFileName) { using (var file = File.Create(indexFileName)) using (var compressor = new ICSharpCode.SharpZipLib.BZip2.BZip2OutputStream(file)) { var serializer = new NetSerializer.Serializer(new Type[] { typeof(Indexes) }); var indexes = new Indexes(); indexes.ChunkIdToFirstNonFreeObjectInChunk = _chunkIdToFirstNonFreeObjectInChunk; indexes.StartOfChunkToChunkId = _startOfChunkToChunkId; indexes.ChunkToReferencingChunks = _chunkToReferencingChunks; indexes.DirectlyRooted = _directlyRooted.ToArray(); indexes.AllRoots = _allRoots; indexes.StaticRootsEnumerated = _staticRootsEnumerated; indexes.ChunkSize = _chunkSize; serializer.Serialize(compressor, indexes); } _context.WriteLine("Wrote index file of size {0}", ((ulong)new FileInfo(indexFileName).Length).ToMemoryUnits()); }
private void PrintTriageInformation(CommandExecutionContext context, TriageInformation triageInformation) { context.WriteLine("MODULES {0} modules loaded", triageInformation.ModuleCount); context.WriteLine("THREADS {0} total threads, {1} managed threads", triageInformation.TotalThreadCount, triageInformation.ManagedThreadCount); context.WriteLine("MEMORY {0} committed, {1} reserved, {2} GC heap", triageInformation.CommittedMemoryBytes.ToMemoryUnits(), triageInformation.ReservedMemoryBytes.ToMemoryUnits(), triageInformation.GCHeapMemoryBytes.ToMemoryUnits()); context.WriteLine("EVENT Last event in thread OSID = {0}, managed = {1}", _triageInformation.FaultingThreadOSID, _triageInformation.IsFaultingThreadManaged); context.WriteLine("EVENT {0}", _triageInformation.EventDescription); context.WriteLine("EVENT Exception {0:X8}", _triageInformation.ExceptionCode); context.WriteLine("EVENT Managed exception {0}", _triageInformation.ManagedExceptionType); context.WriteLine("EVENT Faulting module {0}, method {1}", _triageInformation.FaultingModule, _triageInformation.FaultingMethod); }
private void DisplayChainForThread(UnifiedThread unifiedThread, int depth, HashSet <uint> visitedThreadIds) { if (unifiedThread.IsManagedThread) { var command = String.Format("~ {0}; !mk", unifiedThread.ManagedThreadId); _context.WriteLink(String.Format("{0}+ OS Thread {1}", new string(' ', depth * 2), unifiedThread.OSThreadId), command); } else { _context.Write("+ OS Thread {0}", unifiedThread.OSThreadId); } _context.WriteLine(); if (visitedThreadIds.Contains(unifiedThread.OSThreadId)) { _context.WriteLine("{0}*** DEADLOCK!", new string(' ', depth * 2)); return; } visitedThreadIds.Add(unifiedThread.OSThreadId); DisplayThreadBlockingObjects(unifiedThread, depth, unifiedThread.BlockingObjects, visitedThreadIds); }
private void FillFaultingThreadAndModuleInformation(CommandExecutionContext context) { UnifiedStackTrace stackTrace = new UnifiedStackTrace(_dbgEngTarget.DebuggerInterface, context); _triageInformation.TotalThreadCount = (int)stackTrace.NumThreads; _triageInformation.ManagedThreadCount = stackTrace.Threads.Count(t => t.IsManagedThread); LastEventInformation lastEventInformation = _dbgEngTarget.GetLastEventInformation(); if (lastEventInformation == null) { return; } ThreadInfo faultingThread = stackTrace.Threads.SingleOrDefault(t => t.OSThreadId == lastEventInformation.OSThreadId); if (faultingThread == null) { return; } _triageInformation.FaultingThreadOSID = faultingThread.OSThreadId; _triageInformation.IsFaultingThreadManaged = faultingThread.IsManagedThread; _triageInformation.EventDescription = lastEventInformation.EventDescription; if (lastEventInformation.ExceptionRecord.HasValue) { _triageInformation.ExceptionCode = lastEventInformation.ExceptionRecord.Value.ExceptionCode; } if (faultingThread.IsManagedThread && faultingThread.ManagedThread.CurrentException != null) { _triageInformation.ManagedExceptionType = faultingThread.ManagedThread.CurrentException.Type.Name; } var frames = stackTrace.GetStackTrace(faultingThread.Index); UnifiedStackFrame faultingFrame = frames.FirstOrDefault(f => f.Module != null && !WellKnownMicrosoftModules.Contains(f.Module)); if (faultingFrame != null) { _triageInformation.FaultingModule = faultingFrame.Module; _triageInformation.FaultingMethod = faultingFrame.Method; } if (ShowFaultingStack) { context.WriteLine("Faulting call stack:"); stackTrace.PrintStackTrace(context, frames); } }
public void Execute(CommandExecutionContext context) { if (!CommandHelpers.VerifyHasHeapIndex(context)) { return; } if (!CommandHelpers.VerifyValidObjectAddress(context, ObjectAddress)) { return; } var type = context.Heap.GetObjectType(ObjectAddress); context.WriteLine("Note: unrooted (dead) objects will not have any referencing objects displayed."); context.WriteLine("Object {0:x16} ({1}) is referenced by the following objects:", ObjectAddress, type.Name); foreach (var referencingObj in context.HeapIndex.FindRefs(ObjectAddress)) { string refHex = String.Format("{0:x16}", referencingObj); context.WriteLink(refHex, "!do " + refHex); context.WriteLine(" ({0})", context.Heap.GetObjectType(referencingObj).Name); } context.WriteLine("Object {0:x16} ({1}) references the following objects:", ObjectAddress, type.Name); type.EnumerateRefsOfObject(ObjectAddress, (child, _) => { var childType = context.Heap.GetObjectType(child); if (childType == null || String.IsNullOrEmpty(childType.Name)) { return; } string refHex = String.Format("{0:x16}", child); context.WriteLink(refHex, "!do " + refHex); context.WriteLine(" ({0})", childType.Name); }); }
public void Execute(CommandExecutionContext context) { if (String.IsNullOrEmpty(HeapIndexFileName)) { if (context.TargetType != TargetType.DumpFile) { context.WriteErrorLine("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.WriteErrorLine("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 PrintStackTrace(CommandExecutionContext context, IEnumerable <UnifiedStackFrame> stackTrace) { foreach (var frame in stackTrace) { if (frame.Type == UnifiedStackFrameType.Special) { context.WriteLine("{0,-10}", "Special"); continue; } if (String.IsNullOrEmpty(frame.SourceFileName)) { context.WriteLine("{0,-10} {1,-20:x16} {2}!{3}+0x{4:x}", frame.Type, frame.InstructionPointer, frame.Module, frame.Method, frame.OffsetInMethod); } else { context.WriteLine("{0,-10} {1,-20:x16} {2}!{3} [{4}:{5},{6}]", frame.Type, frame.InstructionPointer, frame.Module, frame.Method, frame.SourceFileName, frame.SourceLineNumber, frame.SourceColumnNumber); } } }
public static void WriteStackTraceToContext(this ClrThread thread, IList<ClrStackFrame> stackTrace, CommandExecutionContext context, bool displayArgumentsAndLocals) { FrameArgumentsAndLocals[] argsAndLocals = displayArgumentsAndLocals ? new FrameArgumentsAndLocalsRetriever(thread, stackTrace, context).ArgsAndLocals : new FrameArgumentsAndLocals[0]; context.WriteLine("{0,-20} {1,-20} {2}", "SP", "IP", "Function"); foreach (var frame in stackTrace) { var sourceLocation = context.SymbolCache.GetFileAndLineNumberSafe(frame); context.WriteLine("{0,-20:X16} {1,-20:X16} {2} {3}", frame.StackPointer, frame.InstructionPointer, frame.DisplayString, sourceLocation == null ? "" : String.Format("[{0}:{1},{2}]", sourceLocation.FilePath, sourceLocation.LineNumber, sourceLocation.ColStart)); var frameArgsAndLocals = argsAndLocals.FirstOrDefault( al => al.MethodName == frame.DisplayString); if (frameArgsAndLocals != null) { frameArgsAndLocals.Arguments.ForEach(a => DisplayOneArgumentOrLocal(context, "arg", a)); frameArgsAndLocals.LocalVariables.ForEach(l => DisplayOneArgumentOrLocal(context, "lcl", l)); } } }
public void Execute(CommandExecutionContext context) { IEnumerable<ClrAppDomain> appDomains = context.Runtime.AppDomains; if (Id != 0) { appDomains = appDomains.Where(ad => ad.Id == Id); } context.WriteLine("{0,-4} {1,-40} {2,-10} {3}", "Id", "Name", "# Modules", "Application Base"); foreach (var appDomain in appDomains) { context.WriteLine("{0,-4} {1,-40} {2,-10} {3}", appDomain.Id, appDomain.Name.TrimEndToLength(40), appDomain.Modules.Count, appDomain.ApplicationBase); if (Id != 0) { foreach (var module in appDomain.Modules) { context.WriteLine(" {0}", module.FileName); } } } }
public void Execute(CommandExecutionContext context) { using (var target = context.CreateTemporaryDbgEngTarget()) { LastEventInformation lastEventInformation = target.GetLastEventInformation(); if (lastEventInformation == null) { context.WriteLine("Last event information is not available"); return; } context.Write("Thread OSID = {0} ", lastEventInformation.OSThreadId); var managedThread = context.Runtime.Threads.SingleOrDefault(t => t.OSThreadId == lastEventInformation.OSThreadId); if (managedThread != null) { context.WriteLine("(managed id = {0})", managedThread.ManagedThreadId); } else { context.WriteLine("(unmanaged)"); } context.WriteLine("{0} - {1}", lastEventInformation.EventType, lastEventInformation.EventDescription); } }
public static void WriteStackTraceToContext(this ClrThread thread, IList <ClrStackFrame> stackTrace, CommandExecutionContext context, bool displayArgumentsAndLocals) { FrameArgumentsAndLocals[] argsAndLocals = displayArgumentsAndLocals ? new FrameArgumentsAndLocalsRetriever(thread, stackTrace, context).ArgsAndLocals : new FrameArgumentsAndLocals[0]; context.WriteLine("{0,-20} {1,-20} {2}", "SP", "IP", "Function"); foreach (var frame in stackTrace) { var sourceLocation = context.SymbolCache.GetFileAndLineNumberSafe(frame); context.WriteLine("{0,-20:X16} {1,-20:X16} {2} {3}", frame.StackPointer, frame.InstructionPointer, frame.DisplayString, sourceLocation == null ? "" : String.Format("[{0}:{1},{2}]", sourceLocation.FilePath, sourceLocation.LineNumber, sourceLocation.ColStart)); var frameArgsAndLocals = argsAndLocals.FirstOrDefault( al => al.MethodName == frame.DisplayString); if (frameArgsAndLocals != null) { frameArgsAndLocals.Arguments.ForEach(a => DisplayOneArgumentOrLocal(context, "arg", a)); frameArgsAndLocals.LocalVariables.ForEach(l => DisplayOneArgumentOrLocal(context, "lcl", l)); } } }
public void Execute(CommandExecutionContext context) { var threadPool = context.Runtime.GetThreadPool(); context.WriteLine("Total threads: {0}", threadPool.TotalThreads); context.WriteLine("Running threads: {0}", threadPool.RunningThreads); context.WriteLine("Idle threads: {0}", threadPool.IdleThreads); context.WriteLine("Max threads: {0}", threadPool.MaxThreads); context.WriteLine("Min threads: {0}", threadPool.MinThreads); context.WriteLine("CPU utilization: {0}% (estimated)", threadPool.CpuUtilization); }
public void Execute(CommandExecutionContext context) { if (OSThreadId == 0) { OSThreadId = context.CurrentThread.OSThreadId; } context.WriteLine("{0,-10} {1,-20} {2}", "Type", "IP", "Function"); using (var target = context.CreateTemporaryDbgEngTarget()) { var stackTracer = new UnifiedStackTraces(target.DebuggerInterface, context); stackTracer.PrintStackTrace(context, (from thr in stackTracer.Threads where thr.OSThreadId == OSThreadId select thr.Index).Single()); } }
public void Execute(CommandExecutionContext context) { _searchRegex = new Regex(SearchString); foreach (var thread in context.Runtime.Threads) { if (ThreadMatchesFilter(thread)) { context.WriteLink( String.Format("Thread {0}", thread.ManagedThreadId), String.Format("~ {0}", thread.ManagedThreadId) ); context.WriteLine(); thread.WriteCurrentStackTraceToContext(context, displayArgumentsAndLocals: false); } } }
private void PrintTriageInformation(CommandExecutionContext context, TriageInformation triageInformation) { context.WriteLine("MODULES {0} modules loaded", triageInformation.ModuleCount); context.WriteLine("THREADS {0} total threads, {1} managed threads", triageInformation.TotalThreadCount, triageInformation.ManagedThreadCount); context.WriteLine("MEMORY {0} committed, {1} reserved, {2} GC heap", triageInformation.CommittedMemoryBytes.ToMemoryUnits(), triageInformation.ReservedMemoryBytes.ToMemoryUnits(), triageInformation.GCHeapMemoryBytes.ToMemoryUnits()); context.WriteLine("EVENT Last event in thread OSID = {0}, managed = {1}", _triageInformation.FaultingThreadOSID, _triageInformation.IsFaultingThreadManaged); context.WriteLine("EVENT {0}", _triageInformation.EventDescription); if (_triageInformation.ExceptionCode != 0) context.WriteLine("EVENT Exception {0:X8}", _triageInformation.ExceptionCode); if (!String.IsNullOrEmpty(_triageInformation.ManagedExceptionType)) context.WriteLine("EVENT Managed exception {0}", _triageInformation.ManagedExceptionType); context.WriteLine("EVENT Faulting module {0}, method {1}", _triageInformation.FaultingModule, _triageInformation.FaultingMethod); }
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); } }
private static void DisplayException(ClrException exception, CommandExecutionContext context) { context.WriteLine("Exception object: {0:x16}", exception.Address); context.WriteLine("Exception type: {0}", exception.Type.Name); var innerException = exception.Inner; context.WriteLine("Message: {0}", exception.GetExceptionMessageSafe()); context.WriteLine("Inner exception: {0}", innerException == null ? "<none>" : String.Format("{0:x16}", innerException.Address)); if (context.TargetType != TargetType.DumpFileNoHeap) { // In no-heap dumps, stuff goes wrong inside DesktopException because some fields can't // be found. It can be fixed with a lot of refactoring (not relying on fields at all and // using offsets instead), but it's probably not such a big deal anyway. context.WriteLine("HResult: {0:x}", exception.HResult); } context.WriteLine("Stack trace:"); ClrThreadExtensions.WriteStackTraceToContext(null, exception.StackTrace, context, displayArgumentsAndLocals: false); }
public void Execute(CommandExecutionContext context) { _context = context; if (!DisplayVirtualMemoryRanges && !DisplayVirtualMemoryStatistics && !DisplayManagedHeapStatistics && !DisplayManagedHeapFragmentation) { _context.WriteLine("No memory information requested. Use one of the " + "command switches, or look at the help: 'help !memstats'"); } if (DisplayVirtualMemoryStatistics) VirtualMemoryStatistics(); if (DisplayVirtualMemoryRanges) VirtualMemoryRanges(); if (DisplayManagedHeapStatistics) ManagedHeapStatistics(); if (DisplayManagedHeapFragmentation) ManagedHeapFragmentation(); }
private static void DisplayOneArgumentOrLocal(CommandExecutionContext context, string which, ArgumentOrLocal argOrLocal) { context.Write(" {0} {1,-10} = {2} ({3},{4} {5} bytes) ", which, argOrLocal.Name, argOrLocal.ValueRaw(), argOrLocal.DynamicTypeName, argOrLocal.StaticAndDynamicTypesAreTheSame ? "" : (" original " + argOrLocal.StaticTypeName + ","), argOrLocal.Size); if (argOrLocal.ObjectAddress != 0) { context.WriteLink("", String.Format("!do {0:x16}", argOrLocal.ObjectAddress)); } else if (argOrLocal.HasNonTrivialValueToDisplay) { context.WriteLink("", String.Format("!do {0:x16} --type {1}", argOrLocal.Location, argOrLocal.ClrType.Name)); } context.WriteLine(); }
private void FillFaultingThreadAndModuleInformation(CommandExecutionContext context) { UnifiedStackTrace stackTrace = new UnifiedStackTrace(_dbgEngTarget.DebuggerInterface, context); _triageInformation.TotalThreadCount = (int)stackTrace.NumThreads; _triageInformation.ManagedThreadCount = stackTrace.Threads.Count(t => t.IsManagedThread); LastEventInformation lastEventInformation = _dbgEngTarget.GetLastEventInformation(); if (lastEventInformation == null) return; ThreadInfo faultingThread = stackTrace.Threads.SingleOrDefault(t => t.OSThreadId == lastEventInformation.OSThreadId); if (faultingThread == null) return; _triageInformation.FaultingThreadOSID = faultingThread.OSThreadId; _triageInformation.IsFaultingThreadManaged = faultingThread.IsManagedThread; _triageInformation.EventDescription = lastEventInformation.EventDescription; if (lastEventInformation.ExceptionRecord.HasValue) { _triageInformation.ExceptionCode = lastEventInformation.ExceptionRecord.Value.ExceptionCode; } if (faultingThread.IsManagedThread && faultingThread.ManagedThread.CurrentException != null) { _triageInformation.ManagedExceptionType = faultingThread.ManagedThread.CurrentException.Type.Name; } var frames = stackTrace.GetStackTrace(faultingThread.Index); UnifiedStackFrame faultingFrame = frames.FirstOrDefault(f => f.Module != null && !WellKnownMicrosoftModules.Contains(f.Module)); if (faultingFrame != null) { _triageInformation.FaultingModule = faultingFrame.Module; _triageInformation.FaultingMethod = faultingFrame.Method; } if (ShowFaultingStack) { context.WriteLine("Faulting call stack:"); stackTrace.PrintStackTrace(context, frames); } }
public void Execute(CommandExecutionContext context) { if (!String.IsNullOrEmpty(TypeRegex)) { try { new Regex(TypeRegex); } catch (ArgumentException) { context.WriteErrorLine("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.WriteErrorLine("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 PrintStackTrace(CommandExecutionContext context, IEnumerable<UnifiedStackFrame> stackTrace) { foreach (var frame in stackTrace) { if (frame.Type == UnifiedStackFrameType.Special) { context.WriteLine("{0,-10}", "Special"); continue; } if (String.IsNullOrEmpty(frame.SourceFileName)) { context.WriteLine("{0,-10} {1,-20:x16} {2}!{3}+0x{4:x}", frame.Type, frame.InstructionPointer, frame.Module, frame.Method, frame.OffsetInMethod); } else { context.WriteLine("{0,-10} {1,-20:x16} {2}!{3} [{4}:{5},{6}]", frame.Type, frame.InstructionPointer, frame.Module, frame.Method, frame.SourceFileName, frame.SourceLineNumber, frame.SourceColumnNumber); } } }
public void Execute(CommandExecutionContext context) { context.WriteLine("{0} CLR threads, {1} CLR thread pool threads, {2} background threads", context.Runtime.Threads.Count, context.Runtime.Threads.Count(t => t.IsThreadPoolThread()), context.Runtime.Threads.Count(t => t.IsBackground)); context.WriteLine("{0,-6} {1,-6} {2,-6} {3,-6} {4,-20} {5,-30}", "MgdId", "OSId", "Lock#", "Apt", "Special", "Exception"); foreach (var thread in context.Runtime.Threads) { context.Write("{0,-6} {1,-6} {2,-6} {3,-6} {4,-20} {5,-30} ", thread.ManagedThreadId, thread.OSThreadId, thread.LockCount, thread.ApartmentDescription(), thread.SpecialDescription(), (thread.CurrentException != null ? thread.CurrentException.Type.Name : "").TrimStartToLength(30)); context.WriteLink("", String.Format("~ {0}; {1}", thread.ManagedThreadId, thread.CurrentException != null ? "!pe" : "!clrstack")); context.WriteLine(); } if (!DisplayNativeThreads) return; context.WriteLine(); context.WriteLine("{0,-6} {1,-6} {2,-10} {3}", "OSId", "MgdId", "ExitCode", "StartAddress"); using (var target = context.CreateTemporaryDbgEngTarget()) { var osThreadIds = target.GetOSThreadIds(); var symbols = (IDebugSymbols)target.DebuggerInterface; var advanced = (IDebugAdvanced2)target.DebuggerInterface; int size; byte[] buffer = new byte[Marshal.SizeOf(typeof(DEBUG_THREAD_BASIC_INFORMATION))]; GCHandle gch = GCHandle.Alloc(buffer, GCHandleType.Pinned); try { for (uint engineThreadId = 0; engineThreadId < osThreadIds.Length; ++engineThreadId) { if (0 != advanced.GetSystemObjectInformation(DEBUG_SYSOBJINFO.THREAD_BASIC_INFORMATION, 0, engineThreadId, buffer, buffer.Length, out size)) continue; var info = (DEBUG_THREAD_BASIC_INFORMATION)Marshal.PtrToStructure( gch.AddrOfPinnedObject(), typeof(DEBUG_THREAD_BASIC_INFORMATION)); var managedThread = context.Runtime.Threads.SingleOrDefault(t => t.OSThreadId == osThreadIds[engineThreadId]); context.Write("{0,-6} {1,-6} {2,-10} {3:x16} ", osThreadIds[engineThreadId], managedThread != null ? managedThread.ManagedThreadId.ToString() : "", info.ExitStatus == 259 ? "active" : info.ExitStatus.ToString(), info.StartOffset); uint symSize; ulong displacement; StringBuilder symbolName = new StringBuilder(2048); if (0 == symbols.GetNameByOffset(info.StartOffset, symbolName, symbolName.Capacity, out symSize, out displacement)) { context.Write("{0} ", symbolName.ToString()); } context.WriteLink("", String.Format("!mk {0}", osThreadIds[engineThreadId])); context.WriteLine(); } } finally { gch.Free(); } } }
public void Execute(CommandExecutionContext context) { if (!String.IsNullOrEmpty(SpecificModule)) { var module = context.Runtime.Modules.FirstOrDefault( m => String.Equals(Path.GetFileName(m.Name), SpecificModule, StringComparison.InvariantCultureIgnoreCase)); if (module != null) { var moduleInfo = context.Runtime.DataTarget.EnumerateModules().Single( m => String.Equals(m.FileName, module.FileName, StringComparison.InvariantCultureIgnoreCase)); context.WriteLine("Module: {0}", module.Name); context.WriteLine("PDB name: {0}", moduleInfo.Pdb.FileName); context.WriteLine("Debug mode: {0}", module.DebuggingMode); } else { // Couldn't find managed module, try to find native: using (var target = context.CreateTemporaryDbgEngTarget()) { var moduleInfo = context.Runtime.DataTarget.EnumerateModules().FirstOrDefault( m => String.Equals(Path.GetFileName(m.FileName), SpecificModule, StringComparison.InvariantCultureIgnoreCase)); if (moduleInfo == null) return; IDebugSymbols3 debugSymbols = (IDebugSymbols3)target.DebuggerInterface; uint loaded, unloaded; if (0 != debugSymbols.GetNumberModules(out loaded, out unloaded)) return; for (uint moduleIdx = 0; moduleIdx < loaded; ++moduleIdx) { StringBuilder name = new StringBuilder(2048); uint nameSize; if (0 != debugSymbols.GetModuleNameString(DEBUG_MODNAME.IMAGE, moduleIdx, 0, name, (uint)name.Capacity, out nameSize)) continue; if (!String.Equals(name.ToString(), moduleInfo.FileName, StringComparison.InvariantCultureIgnoreCase)) continue; DEBUG_MODULE_PARAMETERS[] modInfo = new DEBUG_MODULE_PARAMETERS[1]; if (0 != debugSymbols.GetModuleParameters(1, null, moduleIdx, modInfo)) return; name = new StringBuilder(2048); debugSymbols.GetModuleNameString(DEBUG_MODNAME.SYMBOL_FILE, moduleIdx, 0, name, (uint)name.Capacity, out nameSize); context.WriteLine("Module: {0}", moduleInfo.FileName); context.WriteLine("PDB loaded: {0}", modInfo[0].SymbolType == DEBUG_SYMTYPE.DIA || modInfo[0].SymbolType == DEBUG_SYMTYPE.PDB); context.WriteLine("PDB name: {0}", name.ToString()); } } } return; } context.WriteLine("{0,-20:x16} {1,-10} {2,-20} {3}", "start", "size", "version", "filename"); foreach (var module in context.Runtime.DataTarget.EnumerateModules()) { context.WriteLine("{0,-20:x16} {1,-10:x} {2,-20} {3}", module.ImageBase, module.FileSize, module.Version, module.FileName); } }