WriteLink() public method

public WriteLink ( string text, string command ) : void
text string
command string
return void
コード例 #1
0
ファイル: DumpArray.cs プロジェクト: Pavel-Durov/msos
        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();
            }
        }
コード例 #2
0
        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);
                }
            }
        }
コード例 #3
0
        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);
                }
            }
        }
コード例 #4
0
ファイル: Paths.cs プロジェクト: goldshtn/msos
        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.");
            }
        }
コード例 #5
0
        private void ManagedHeapFragmentation()
        {
            var   freeSpaceBySegment = new Dictionary <ClrSegment, ulong>();
            ulong totalFreeSize      = 0;

            foreach (ClrSegment segment in _context.Heap.Segments)
            {
                for (ulong currentObject = segment.FirstObject; currentObject != 0;
                     currentObject = segment.NextObject(currentObject))
                {
                    ClrType type = _context.Heap.GetObjectType(currentObject);
                    if (type != null && type.IsFree)
                    {
                        ulong size = type.GetSize(currentObject);
                        if (!freeSpaceBySegment.ContainsKey(segment))
                        {
                            freeSpaceBySegment.Add(segment, size);
                        }
                        else
                        {
                            freeSpaceBySegment[segment] += size;
                        }
                        totalFreeSize += size;
                    }
                }
            }

            _context.WriteLine("Fragmentation statistics:");
            _context.WriteLine(
                "{0,-4} {1,-20} {2,-12} {3,-12} {4,-12} {5,-12} {6,-10} {7,-10}",
                "#", "Base", "Size", "Committed", "Reserved", "Fragmented", "% Frag", "Type");
            for (int segmentIdx = 0; segmentIdx < _context.Heap.Segments.Count; ++segmentIdx)
            {
                var segment    = _context.Heap.Segments[segmentIdx];
                var fragmented = freeSpaceBySegment.ContainsKey(segment) ? freeSpaceBySegment[segment] : 0;
                _context.Write(
                    "{0,-4} {1,-20:x16} {2,-12} {3,-12} {4,-12} {5,-12} {6,-10:0.00%} {7,-5} ",
                    segmentIdx,
                    segment.Start,
                    segment.Length.ToMemoryUnits(),
                    (segment.CommittedEnd - segment.Start).ToMemoryUnits(),
                    (segment.ReservedEnd - segment.Start).ToMemoryUnits(),
                    fragmented.ToMemoryUnits(),
                    fragmented / (double)segment.Length,
                    segment.IsLarge ? "LOH" : "SOH");
                _context.WriteLink(
                    "",
                    String.Format("!hq tabular from o in ObjectsInSegment({0}) " +
                                  "group (long)o.__Size by o.__Type into g " +
                                  "let totalSize = g.Sum() " +
                                  "orderby totalSize ascending " +
                                  "select new {{ Type = g.Key, TotalSize = totalSize }}",
                                  segmentIdx)
                    );
                _context.WriteLine();
            }
            _context.WriteLine();
            _context.WriteLine("Total size of free objects: {0}", totalFreeSize.ToMemoryUnits());
            _context.WriteLine();
        }
コード例 #6
0
        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.");
            }
        }
コード例 #7
0
 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();
 }
コード例 #8
0
        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);
                }
            }
        }
コード例 #9
0
 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();
     }
 }
コード例 #10
0
        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);
        }
コード例 #11
0
ファイル: Refs.cs プロジェクト: tiandian/msos
        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);
            });
        }
コード例 #12
0
ファイル: DumpStackObjects.cs プロジェクト: goldshtn/msos
        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();
            }
        }
コード例 #13
0
ファイル: DumpStackObjects.cs プロジェクト: tiandian/msos
        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();
            }
        }
コード例 #14
0
ファイル: FindStack.cs プロジェクト: goldshtn/msos
 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);
         }
     }
 }
コード例 #15
0
 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);
         }
     }
 }
コード例 #16
0
ファイル: MemStats.cs プロジェクト: tiandian/msos
        private void ManagedHeapFragmentation()
        {
            var   freeSpaceBySegment = _context.Heap.GetFreeSpaceBySegment();
            ulong totalFreeSize      = (ulong)freeSpaceBySegment.Values.Sum(f => (long)f);

            _context.WriteLine("Fragmentation statistics:");
            _context.WriteLine(
                "{0,-4} {1,-20} {2,-12} {3,-12} {4,-12} {5,-12} {6,-10} {7,-10}",
                "#", "Base", "Size", "Committed", "Reserved", "Fragmented", "% Frag", "Type");
            for (int segmentIdx = 0; segmentIdx < _context.Heap.Segments.Count; ++segmentIdx)
            {
                var segment    = _context.Heap.Segments[segmentIdx];
                var fragmented = freeSpaceBySegment.ContainsKey(segment) ? freeSpaceBySegment[segment] : 0;
                _context.Write(
                    "{0,-4} {1,-20:x16} {2,-12} {3,-12} {4,-12} {5,-12} {6,-10:0.00%} {7,-5} ",
                    segmentIdx,
                    segment.Start,
                    segment.Length.ToMemoryUnits(),
                    (segment.CommittedEnd - segment.Start).ToMemoryUnits(),
                    (segment.ReservedEnd - segment.Start).ToMemoryUnits(),
                    fragmented.ToMemoryUnits(),
                    fragmented / (double)segment.Length,
                    segment.IsLarge ? "LOH" : "SOH");
                _context.WriteLink(
                    "",
                    String.Format("!hq tabular from o in ObjectsInSegment({0}) " +
                                  "group (long)o.__Size by o.__Type into g " +
                                  "let totalSize = g.Sum() " +
                                  "orderby totalSize ascending " +
                                  "select new {{ Type = g.Key, TotalSize = totalSize }}",
                                  segmentIdx)
                    );
                _context.WriteLine();
            }
            _context.WriteLine();
            _context.WriteLine("Total size of free objects: {0}", totalFreeSize.ToMemoryUnits());
            _context.WriteLine();
        }
コード例 #17
0
ファイル: ClrThreadExtensions.cs プロジェクト: goldshtn/msos
 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();
 }
コード例 #18
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);
                    }
                }
            }
        }
コード例 #19
0
ファイル: Threads.cs プロジェクト: tiandian/msos
        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();
                }
            }
        }
コード例 #20
0
ファイル: FReachableQueue.cs プロジェクト: goldshtn/msos
        public void Execute(CommandExecutionContext context)
        {
            var heap = context.Runtime.GetHeap();
            var readyForFinalization = context.Runtime.EnumerateFinalizerQueueObjectAddresses().ToList();
            ulong totalCount = 0;
            if (StatisticsOnly)
            {
                context.WriteLine("{0,-10} {1,-10} {2}", "Count", "Size", "Class Name");
                var query = from obj in readyForFinalization
                            let type = heap.GetObjectType(obj)
                            where type != null && !String.IsNullOrEmpty(type.Name)
                            let size = (long)type.GetSize(obj)
                            group size by type.Name into g
                            let totalSize = g.Sum()
                            let count = g.Count()
                            orderby totalSize descending
                            select new { Count = count, Size = totalSize, ClassName = g.Key };
                foreach (var row in query)
                {
                    context.WriteLine("{0,-10} {1,-10} {2}", row.Count, row.Size, row.ClassName);
                    totalCount += (ulong)row.Count;
                }
            }
            else
            {
                context.WriteLine("{0,-20} {1,-10} {2}", "Address", "Size", "Class Name");
                foreach (var objPtr in readyForFinalization)
                {
                    var type = heap.GetObjectType(objPtr);
                    if (type == null || String.IsNullOrEmpty(type.Name))
                        return;

                    context.WriteLink(
                        String.Format("{0,-20:x16} {1,-10} {2}", objPtr, type.GetSize(objPtr), type.Name),
                        String.Format("!do {0:x16}", objPtr)
                        );
                    context.WriteLine();
                    ++totalCount;
                }
            }
            context.WriteLine("# of objects ready for finalization: {0}", totalCount);
            context.WriteLine("Memory reachable from these objects: {0}",
                heap.SizeReachableFromObjectSet(readyForFinalization).ToMemoryUnits());

            var finalizerThread = context.Runtime.Threads.SingleOrDefault(t => t.IsFinalizer);
            if (finalizerThread != null && finalizerThread.BlockingObjects.Count > 0)
            {
                context.WriteLine();
                context.WriteLine("The finalizer thread is blocked! Blocking objects:");
                foreach (var blockingObject in finalizerThread.BlockingObjects)
                {
                    context.Write("\t{0} ", blockingObject.Reason);
                    string objHex = String.Format("{0:x16}", blockingObject.Object);
                    context.WriteLink(objHex, "!do " + objHex);
                    context.WriteLine();
                }
                context.WriteLine("Blocked at:");
                foreach (var frame in finalizerThread.StackTrace.Take(3))
                {
                    context.WriteLine("\t" + frame.DisplayString);
                }
                context.WriteLink(
                    "\t... view full stack",
                    String.Format("~ {0}; !clrstack", finalizerThread.ManagedThreadId));
                context.WriteLine();
            }
        }
コード例 #21
0
        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();
            }
        }
コード例 #22
0
ファイル: Threads.cs プロジェクト: goldshtn/msos
        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();
                }
            }
        }
コード例 #23
0
        public void Execute(CommandExecutionContext context)
        {
            var   heap = context.Runtime.GetHeap();
            var   readyForFinalization = context.Runtime.EnumerateFinalizerQueue().ToList();
            ulong totalCount           = 0;

            if (StatisticsOnly)
            {
                context.WriteLine("{0,-10} {1,-10} {2}", "Count", "Size", "Class Name");
                var query = from obj in readyForFinalization
                            let type = heap.GetObjectType(obj)
                                       where type != null && !String.IsNullOrEmpty(type.Name)
                                       let size = (long)type.GetSize(obj)
                                                  group size by type.Name into g
                                                  let totalSize                         = g.Sum()
                                                                              let count = g.Count()
                                                                                          orderby totalSize descending
                                                                                          select new { Count = count, Size = totalSize, ClassName = g.Key };
                foreach (var row in query)
                {
                    context.WriteLine("{0,-10} {1,-10} {2}", row.Count, row.Size, row.ClassName);
                    totalCount += (ulong)row.Count;
                }
            }
            else
            {
                context.WriteLine("{0,-20} {1,-10} {2}", "Address", "Size", "Class Name");
                foreach (var objPtr in readyForFinalization)
                {
                    var type = heap.GetObjectType(objPtr);
                    if (type == null || String.IsNullOrEmpty(type.Name))
                    {
                        return;
                    }

                    context.WriteLink(
                        String.Format("{0,-20:x16} {1,-10} {2}", objPtr, type.GetSize(objPtr), type.Name),
                        String.Format("!do {0:x16}", objPtr)
                        );
                    context.WriteLine();
                    ++totalCount;
                }
            }
            context.WriteLine("# of objects ready for finalization: {0}", totalCount);
            context.WriteLine("Memory reachable from these objects: {0}",
                              heap.SizeReachableFromObjectSet(readyForFinalization).ToMemoryUnits());

            var finalizerThread = context.Runtime.Threads.SingleOrDefault(t => t.IsFinalizer);

            if (finalizerThread != null && finalizerThread.BlockingObjects.Count > 0)
            {
                context.WriteLine();
                context.WriteLine("The finalizer thread is blocked! Blocking objects:");
                foreach (var blockingObject in finalizerThread.BlockingObjects)
                {
                    context.Write("\t{0} ", blockingObject.Reason);
                    string objHex = String.Format("{0:x16}", blockingObject.Object);
                    context.WriteLink(objHex, "!do " + objHex);
                    context.WriteLine();
                }
                context.WriteLine("Blocked at:");
                foreach (var frame in finalizerThread.StackTrace.Take(3))
                {
                    context.WriteLine("\t" + frame.DisplayString);
                }
                context.WriteLink(
                    "\t... view full stack",
                    String.Format("~ {0}; !clrstack", finalizerThread.ManagedThreadId));
                context.WriteLine();
            }
        }