public Node(LinkedListNodeCache linkedListNodeCache, ulong address) { _Cache = linkedListNodeCache; _Address = address; _Variable = _Cache._Engine.Memory.CreateLiveVariable(address + (uint)_Cache._Start, _Cache._Length) ?? throw new Exception($"Failed to create live variable at 0x{address:x8}"); }
public NodeSource(ILiveWatchEngine engine) { Engine = engine; _TCBType = (IPinnedVariableStructType)engine.Symbols.LookupType("TCB_t", true); _QueueType = (IPinnedVariableStructType)engine.Symbols.LookupType("Queue_t"); var xStateListItem_Offset = _TCBType.LookupMember("xStateListItem", true).Offset; xEventListItem_Offset = _TCBType.LookupMember("xEventListItem", true).Offset; var listItemType = (IPinnedVariableStructType)engine.Symbols.LookupType("ListItem_t", true); var pvOwner_Offset = (int)listItemType.LookupMember("pvOwner", true).Offset; var pxNext_Offset = (int)listItemType.LookupMember("pxNext", true).Offset; StateThreadListCache = new LinkedListNodeCache(engine, pvOwner_Offset, pxNext_Offset); EventThreadListCache = new LinkedListNodeCache(engine, pvOwner_Offset, pxNext_Offset); _pxCurrentTCB = engine.CreateLiveVariable("pxCurrentTCB", true); _uxCurrentNumberOfTasks = engine.CreateLiveVariable("uxCurrentNumberOfTasks", true); foreach (var pxReadyTaskList in engine.Symbols.LookupVariable("pxReadyTasksLists")?.LookupChildren(0) ?? new IPinnedVariable[0]) { ThreadList.Locate(_AllThreadLists, engine, pxReadyTaskList, ThreadListType.Ready, xStateListItem_Offset); } ThreadList.Locate(_AllThreadLists, engine, engine.Symbols.LookupVariable("xDelayedTaskList1"), ThreadListType.Delayed, xStateListItem_Offset); ThreadList.Locate(_AllThreadLists, engine, engine.Symbols.LookupVariable("xDelayedTaskList2"), ThreadListType.Delayed, xStateListItem_Offset); ThreadList.Locate(_AllThreadLists, engine, engine.Symbols.LookupVariable("xSuspendedTaskList"), ThreadListType.Suspended, xStateListItem_Offset); _Children = new ILiveWatchNode[] { new KernelNode(this, engine), new ThreadListNode(this), new QueueListNode(this), new HeapStructureNode(this) }; }
public ThreadLookup(NodeSource root, IEnumerable <ThreadList> threadLists, bool includeCurrentTCB, LinkedListNodeCache cache) { _Root = root; _ThreadLists = threadLists; _IncludeCurrentTCB = includeCurrentTCB; _Cache = cache; foreach (var list in threadLists) { _ProcessedNodes.Add(list.EndNodeAddress); } }
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; } } }