Esempio n. 1
0
        protected override void Update()
        {
            // Load symbols if they are not already loaded.
            this.LoadSymbols();

            var threads = Windows.GetProcessThreads(_pid);
            Dictionary <int, ThreadItem> newdictionary = new Dictionary <int, ThreadItem>(this.Dictionary);

            if (threads == null)
            {
                threads = new Dictionary <int, SystemThreadInformation>();
            }

            // look for dead threads
            foreach (int tid in Dictionary.Keys)
            {
                if (!threads.ContainsKey(tid))
                {
                    ThreadItem item = this.Dictionary[tid];

                    if (item.ThreadQueryLimitedHandle != null)
                    {
                        item.ThreadQueryLimitedHandle.Dispose();
                    }

                    this.OnDictionaryRemoved(item);
                    newdictionary.Remove(tid);
                }
            }

            // Get resolve results.
            _messageQueue.Listen();

            // look for new threads
            foreach (int tid in threads.Keys)
            {
                var t = threads[tid];

                if (!Dictionary.ContainsKey(tid))
                {
                    ThreadItem item = new ThreadItem();

                    item.RunId           = this.RunCount;
                    item.Tid             = tid;
                    item.ContextSwitches = t.ContextSwitchCount;
                    item.WaitReason      = t.WaitReason;

                    try
                    {
                        item.ThreadQueryLimitedHandle = new ThreadHandle(tid, Program.MinThreadQueryRights);

                        try
                        {
                            item.PriorityI = (int)item.ThreadQueryLimitedHandle.GetBasePriorityWin32();
                            item.Priority  = item.ThreadQueryLimitedHandle.GetBasePriorityWin32().ToString();
                        }
                        catch
                        { }

                        if (KProcessHacker.Instance != null)
                        {
                            try
                            {
                                item.IsGuiThread = KProcessHacker.Instance.KphGetThreadWin32Thread(item.ThreadQueryLimitedHandle) != 0;
                            }
                            catch
                            { }
                        }

                        if (OSVersion.HasCycleTime)
                        {
                            try
                            {
                                item.Cycles = item.ThreadQueryLimitedHandle.GetCycleTime();
                            }
                            catch
                            { }
                        }
                    }
                    catch
                    { }

                    if (KProcessHacker.Instance != null && item.ThreadQueryLimitedHandle != null)
                    {
                        try
                        {
                            item.StartAddressI =
                                KProcessHacker.Instance.GetThreadStartAddress(item.ThreadQueryLimitedHandle).ToIntPtr();
                        }
                        catch
                        { }
                    }
                    else
                    {
                        try
                        {
                            using (ThreadHandle thandle =
                                       new ThreadHandle(tid, ThreadAccess.QueryInformation))
                            {
                                item.StartAddressI = thandle.GetWin32StartAddress();
                            }
                        }
                        catch
                        {
                            item.StartAddressI = t.StartAddress;
                        }
                    }

                    if (_moduleLoadCompletedEvent.Wait(0))
                    {
                        try
                        {
                            item.StartAddress = this.GetThreadBasicStartAddress(
                                item.StartAddressI.ToUInt64(), out item.StartAddressLevel);
                        }
                        catch
                        { }
                    }

                    if (string.IsNullOrEmpty(item.StartAddress))
                    {
                        item.StartAddress      = Utils.FormatAddress(item.StartAddressI);
                        item.StartAddressLevel = SymbolResolveLevel.Address;
                    }

                    this.QueueThreadResolveStartAddress(tid, item.StartAddressI.ToUInt64());

                    newdictionary.Add(tid, item);
                    this.OnDictionaryAdded(item);
                }
                // look for modified threads
                else
                {
                    ThreadItem item    = Dictionary[tid];
                    ThreadItem newitem = item.Clone() as ThreadItem;

                    newitem.JustResolved         = false;
                    newitem.ContextSwitchesDelta = t.ContextSwitchCount - newitem.ContextSwitches;
                    newitem.ContextSwitches      = t.ContextSwitchCount;
                    newitem.WaitReason           = t.WaitReason;

                    try
                    {
                        newitem.PriorityI = (int)newitem.ThreadQueryLimitedHandle.GetBasePriorityWin32();
                        newitem.Priority  = newitem.ThreadQueryLimitedHandle.GetBasePriorityWin32().ToString();
                    }
                    catch
                    { }

                    if (KProcessHacker.Instance != null)
                    {
                        try
                        {
                            newitem.IsGuiThread = KProcessHacker.Instance.KphGetThreadWin32Thread(newitem.ThreadQueryLimitedHandle) != 0;
                        }
                        catch
                        { }
                    }

                    if (OSVersion.HasCycleTime)
                    {
                        try
                        {
                            ulong thisCycles = newitem.ThreadQueryLimitedHandle.GetCycleTime();

                            newitem.CyclesDelta = thisCycles - newitem.Cycles;
                            newitem.Cycles      = thisCycles;
                        }
                        catch
                        { }
                    }

                    if (newitem.StartAddressLevel == SymbolResolveLevel.Address)
                    {
                        if (_moduleLoadCompletedEvent.Wait(0))
                        {
                            newitem.StartAddress = this.GetThreadBasicStartAddress(
                                newitem.StartAddressI.ToUInt64(), out newitem.StartAddressLevel);
                        }

                        // If we couldn't resolve it to a module+offset,
                        // use the StartAddress (instead of the Win32StartAddress)
                        // and queue the resolve again.
                        if (
                            item.StartAddressLevel == SymbolResolveLevel.Address &&
                            item.JustResolved)
                        {
                            if (item.StartAddressI != t.StartAddress)
                            {
                                item.StartAddressI = t.StartAddress;
                                this.QueueThreadResolveStartAddress(tid, item.StartAddressI.ToUInt64());
                            }
                        }
                    }

                    if (
                        newitem.ContextSwitches != item.ContextSwitches ||
                        newitem.ContextSwitchesDelta != item.ContextSwitchesDelta ||
                        newitem.Cycles != item.Cycles ||
                        newitem.CyclesDelta != item.CyclesDelta ||
                        newitem.IsGuiThread != item.IsGuiThread ||
                        newitem.Priority != item.Priority ||
                        newitem.StartAddress != item.StartAddress ||
                        newitem.WaitReason != item.WaitReason ||
                        item.JustResolved
                        )
                    {
                        newdictionary[tid] = newitem;
                        this.OnDictionaryModified(item, newitem);
                    }
                }
            }

            Dictionary = newdictionary;
        }