Beispiel #1
0
        public void Execute(CommandExecutionContext context)
        {
            _context = context;

            try
            {
                SetStrategy();

                if (SpecificOSThreadId != 0)
                {
                    UnifiedThread thread = SpecificThread;

                    if (SpecificThread == null)
                    {
                        _context.WriteErrorLine("There is no thread with the id '{0}'.", SpecificOSThreadId);
                        return;
                    }

                    DisplayChainForThread(thread, 0, new HashSet <uint>());
                }
                else
                {
                    _threads.ForEach(thread => DisplayChainForThread(thread, 0, new HashSet <uint>()));
                }
            }
            finally
            {
                _temporaryDbgEngTarget?.Dispose();
            }
        }
Beispiel #2
0
        private void DisplayThreadBlockingObjects(UnifiedThread unifiedThread,
                                                  int depth, List <UnifiedBlockingObject> blockingObjects, HashSet <uint> visitedThreadIds)
        {
            foreach (var blockingObject in unifiedThread.BlockingObjects)
            {
                _context.Write("{0}| {1} {2}", new string(' ', (depth + 1) * 2), blockingObject.Reason, blockingObject.ReasonDescription);

                if (!String.IsNullOrEmpty(blockingObject.KernelObjectName))
                {
                    _context.Write(
                        String.Format("{0:x16} {1} {2}", blockingObject.Handle,
                                      blockingObject.KernelObjectTypeName, blockingObject.KernelObjectName));
                }

                if (blockingObject.Type == UnifiedBlockingType.ClrBlockingObject)
                {
                    var type = _context.Heap.GetObjectType(blockingObject.ManagedObjectAddress);
                    if (type != null && !String.IsNullOrEmpty(type.Name))
                    {
                        _context.WriteLink(
                            String.Format("{0:x16} {1}", blockingObject.ManagedObjectAddress, type.Name),
                            String.Format("!do {0:x16}", blockingObject.ManagedObjectAddress));
                    }
                    else
                    {
                        _context.Write("{0:x16}", blockingObject.ManagedObjectAddress);
                    }
                }

                _context.WriteLine();

                foreach (var owner in blockingObject.OwnerOSThreadIds)
                {
                    var thread = _threads.SingleOrDefault(t => t.OSThreadId == owner);
                    // We won't necessarily have that thread on our list because it might be
                    // a thread in another process, e.g. for mutexes.
                    if (thread != null)
                    {
                        DisplayChainForThread(thread, depth + 2, visitedThreadIds);
                    }
                }
            }
        }
Beispiel #3
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);
        }
Beispiel #4
0
        private void DisplayThreadBlockingObjects(UnifiedThread unifiedThread,
            int depth, List<UnifiedBlockingObject> blockingObjects, HashSet<uint> visitedThreadIds)
        {
            foreach (var blockingObject in unifiedThread.BlockingObjects)
            {
                _context.Write("{0}| {1} ", new string(' ', (depth + 1) * 2), blockingObject.Reason);

                if (!String.IsNullOrEmpty(blockingObject.KernelObjectName))
                {
                    _context.Write(
                        String.Format("{0:x16} {1} {2}", blockingObject.Handle,
                        blockingObject.KernelObjectTypeName, blockingObject.KernelObjectName));
                }

                if (blockingObject.Type == UnifiedBlockingType.ClrBlockingObject)
                {
                    var type = _context.Heap.GetObjectType(blockingObject.ManagedObjectAddress);
                    if (type != null && !String.IsNullOrEmpty(type.Name))
                    {
                        _context.WriteLink(
                            String.Format("{0:x16} {1}", blockingObject.ManagedObjectAddress, type.Name),
                            String.Format("!do {0:x16}", blockingObject.ManagedObjectAddress));
                    }
                    else
                    {
                        _context.Write("{0:x16}", blockingObject.ManagedObjectAddress);
                    }
                }

                _context.WriteLine();

                foreach (var owner in blockingObject.OwnerOSThreadIds)
                {
                    var thread = _threads.SingleOrDefault(t => t.OSThreadId == owner);
                    // We won't necessarily have that thread on our list because it might be
                    // a thread in another process, e.g. for mutexes.
                    if (thread != null)
                        DisplayChainForThread(thread, depth + 2, visitedThreadIds);
                }
            }
        }
Beispiel #5
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);
        }