Пример #1
0
        Dictionary <ulong, ThreadListType> RunDiscoveryIteration(bool ignoreCachedMemoryValues, out int expectedThreads)
        {
            LiveVariableQueryMode queryMode = ignoreCachedMemoryValues ? LiveVariableQueryMode.QueryDirectly : LiveVariableQueryMode.UseCacheIfAvailable;

            Dictionary <ulong, ThreadListType> result = new Dictionary <ulong, ThreadListType>();

            expectedThreads = (int)_Root._uxCurrentNumberOfTasks.GetValue(queryMode).ToUlong();
            if (expectedThreads < 0 || expectedThreads > 4096)
            {
                throw new Exception("Unexpected FreeRTOS thread count: " + expectedThreads);
            }

            foreach (var list in _ThreadLists)
            {
                list.Walk(_Root.Engine, result, _ProcessedNodes, expectedThreads + 1, _Cache, queryMode);
            }

            if (_IncludeCurrentTCB)
            {
                var pxCurrentTCB = _Root._pxCurrentTCB.GetValue(queryMode).ToUlong();
                if (pxCurrentTCB != 0)
                {
                    result[pxCurrentTCB] = ThreadListType.Running;
                }
            }

            return(result);
        }
Пример #2
0
        public void Walk(ILiveWatchEngine engine,
                         Dictionary <ulong, ThreadListType> result,
                         HashSet <ulong> processedNodes,
                         int maxThreadsToLoad,
                         LinkedListNodeCache nodeCache,
                         LiveVariableQueryMode queryMode)
        {
            int   threadsFound = 0;
            ulong pxNext       = 0;

            for (var pListNode = xListEnd_pxNext.GetValue(queryMode).ToUlong(); pListNode != 0 && !processedNodes.Contains(pListNode); pListNode = pxNext, threadsFound++)
            {
                if (threadsFound >= maxThreadsToLoad)
                {
                    break;
                }

                processedNodes.Add(pListNode);

                try
                {
                    var pTCB = pListNode - _ListItemOffsetInTCB;

                    var cachedListNode = nodeCache.ProvideNode(pListNode);

                    cachedListNode.ReadValues(queryMode, out ulong pvOwner, out pxNext);

                    if (pvOwner != pTCB)
                    {
                        if ((uint)pvOwner == uint.MaxValue)
                        {
                            //This is the end-of-list node. Continue checking past it.
                            continue;
                        }
                        else
                        {
                            //The list node doesn't point to the object itself anymore. Most likely, it has been freed and reused.
                            cachedListNode.RemoveFromCache();
                            break;
                        }
                    }

                    result[pTCB] = Type;
                }
                catch (Exception ex)
                {
                    engine.LogException(ex, $"failed to process TCB node at {pListNode}");
                    break;
                }
            }
        }
Пример #3
0
            ulong[] RunSingleDiscoveryIteration(out int expectedCount, LiveVariableQueryMode queryMode = LiveVariableQueryMode.UseCacheIfAvailable)
            {
                expectedCount = (int)(_ThreadList?.uxNumberOfItems?.GetValue().ToUlong() ?? 0);
                if (expectedCount == 0)
                {
                    return(new ulong[0]);
                }

                Dictionary <ulong, ThreadListType> result = new Dictionary <ulong, ThreadListType>();
                HashSet <ulong> processedNodes            = new HashSet <ulong>();

                _ThreadList.Walk(_Queue._Engine, result, processedNodes, expectedCount * 2, _Queue._Root.EventThreadListCache, queryMode);
                return(result.Keys.ToArray());
            }
Пример #4
0
            public void ReadValues(LiveVariableQueryMode queryMode, out ulong pvOwner, out ulong pxNext)
            {
                var value = _Variable.GetValue(queryMode);

                if (!value.IsValid)
                {
                    pvOwner = pxNext = 0;
                }
                else
                {
                    pvOwner = BitConverter.ToUInt32(value.Value, _Cache.pvOwner_RelativeOffset);
                    pxNext  = BitConverter.ToUInt32(value.Value, _Cache.pxNext_RelativeOffset);
                }
            }
Пример #5
0
            public override LiveWatchNodeState UpdateState(LiveWatchUpdateContext context)
            {
                if (_ThreadList == null)
                {
                    return(base.UpdateState(context));
                }

                RawValue = _ThreadList.uxNumberOfItems.GetValue();

                LiveVariableQueryMode queryMode = LiveVariableQueryMode.UseCacheIfAvailable;

                ulong[] taskAddresses = null;
                bool    mismatch      = true;

                for (int iter = 0; iter < 3; iter++)
                {
                    taskAddresses = RunSingleDiscoveryIteration(out var expectedCount, queryMode);
                    if (taskAddresses.Length == expectedCount)
                    {
                        mismatch = false;
                        break;
                    }
                    queryMode = LiveVariableQueryMode.QueryDirectly;
                }

                string value = "---";

                if (taskAddresses.Length > 0)
                {
                    value = string.Join(", ", taskAddresses.Select(_Queue._Root.GetThreadName).ToArray());
                }

                if (mismatch)
                {
                    value += " (imprecise)";
                }

                return(new LiveWatchNodeState
                {
                    Value = value,
                    Icon = LiveWatchNodeIcon.Thread,
                });
            }