/// <summary> /// Returns a list of modules for the stack 'stackIdx'. It also updates the interning table stackModuleLists, so /// that the entry cooresponding to stackIdx remembers the answer. This can speed up processing alot since many /// stacks have the same prefixes to root. /// </summary> private ModuleList GetModulesForStack(ModuleList[] stackModuleLists, StackSourceCallStackIndex stackIdx) { var ret = stackModuleLists[(int)stackIdx]; if (ret == null) { // ret = the module list for the rest of the frames. var callerIdx = GetCallerIndex(stackIdx); if (callerIdx != StackSourceCallStackIndex.Invalid) { ret = GetModulesForStack(stackModuleLists, callerIdx); } // Compute the module for the top most frame, and add it to the list (if we find a module) TraceModuleFile module = null; var frameIdx = GetFrameIndex(stackIdx); if (frameIdx != StackSourceFrameIndex.Invalid) { var codeAddress = GetFrameCodeAddress(frameIdx); if (codeAddress != CodeAddressIndex.Invalid) { var moduleFileIdx = TraceLog.CallStacks.CodeAddresses.ModuleFileIndex(codeAddress); if (moduleFileIdx != ModuleFileIndex.Invalid) { module = TraceLog.ModuleFiles[moduleFileIdx]; ret = ModuleList.SetAdd(module, ret); } } } stackModuleLists[(int)stackIdx] = ret; } return(ret); }
private bool ReasonableTopFrame(StackSourceCallStackIndex callStackIndex) { uint index = (uint)callStackIndex - (uint)StackSourceCallStackIndex.Start; var stack = m_log.CallStacks[(CallStackIndex)callStackIndex]; if (index < (uint)m_log.CallStacks.MaxCallStackIndex) { CodeAddressIndex codeAddressIndex = m_log.CallStacks.CodeAddressIndex((CallStackIndex)index); ModuleFileIndex moduleFileIndex = m_log.CallStacks.CodeAddresses.ModuleFileIndex(codeAddressIndex); if (m_goodTopModuleIndex == moduleFileIndex) // optimization { return(true); } TraceModuleFile moduleFile = m_log.CallStacks.CodeAddresses.ModuleFile(codeAddressIndex); if (moduleFile == null) { return(false); } // We allow things that end in ntdll to be considered unbroken (TODO is this too strong?) if (!moduleFile.FilePath.EndsWith("ntdll.dll", StringComparison.OrdinalIgnoreCase)) { return(false); } m_goodTopModuleIndex = moduleFileIndex; return(true); } return(false); }
public static ModuleList SetAdd(TraceModuleFile module, ModuleList list) { if (!Member(module, list)) { return(new ModuleList(module, list)); } return(list); }
private static bool ShouldIgnoreFrame(TraceMethod method, TraceModuleFile module) { // TODO Make it optional to ignore kernel frames, and if so -- do it more accurately if (module != null) { return(module.FilePath.EndsWith(".sys") || module.Name == "hal" || module.Name == "ntoskrnl"); } return(false); }
public static bool Member(TraceModuleFile module, ModuleList rest) { while (rest != null) { if ((object)module == (object)rest.Module) { return(true); } rest = rest.Next; } return(false); }
private bool ReasonableTopFrame(StackSourceCallStackIndex callStackIndex, ThreadIndex threadIndex) { uint index = (uint)callStackIndex - (uint)StackSourceCallStackIndex.Start; var stack = m_log.CallStacks[(CallStackIndex)callStackIndex]; if (index < (uint)m_log.CallStacks.Count) { CodeAddressIndex codeAddressIndex = m_log.CallStacks.CodeAddressIndex((CallStackIndex)index); ModuleFileIndex moduleFileIndex = m_log.CallStacks.CodeAddresses.ModuleFileIndex(codeAddressIndex); if (m_goodTopModuleIndex == moduleFileIndex) // optimization { return(true); } TraceModuleFile moduleFile = m_log.CallStacks.CodeAddresses.ModuleFile(codeAddressIndex); if (moduleFile == null) { return(false); } // We allow things that end in ntdll to be considered unbroken (TODO is this too strong?) if (moduleFile.FilePath.EndsWith("ntdll.dll", StringComparison.OrdinalIgnoreCase)) { m_goodTopModuleIndex = moduleFileIndex; return(true); } // The special processes 4 (System) and 0 (Kernel) can stay in the kernel without being broken. if (moduleFile.FilePath.EndsWith("ntoskrnl.exe", StringComparison.OrdinalIgnoreCase)) { var processId = m_log.Threads[threadIndex].Process.ProcessID; if (processId == 4 || processId == 0) { m_goodTopModuleIndex = moduleFileIndex; return(true); } } return(false); } return(false); }
/// <summary> /// Get the call tree node for the specified symbol. /// </summary> /// <param name="symbolName">The symbol.</param> /// <returns>The call tree node representing the symbol, or null if the symbol is not found.</returns> public CallTreeNodeBase GetCallTreeNode(string symbolName) { string[] symbolParts = symbolName.Split(SymbolSeparator); if (symbolParts.Length != 2) { return(null); } // Try to get the call tree node. CallTreeNodeBase node = FindNodeByName(Regex.Escape(symbolName)); // Check to see if the node matches. if (node.Name.StartsWith(symbolName, StringComparison.OrdinalIgnoreCase)) { return(node); } // Check to see if we should attempt to load symbols. if (_traceLog != null && _symbolReader != null && !_resolvedSymbolModules.Contains(symbolParts[0])) { // Look for an unresolved symbols node for the module. string unresolvedSymbolsNodeName = symbolParts[0] + "!?"; node = FindNodeByName(unresolvedSymbolsNodeName); if (node.Name.Equals(unresolvedSymbolsNodeName, StringComparison.OrdinalIgnoreCase)) { // Symbols haven't been resolved yet. Try to resolve them now. TraceModuleFile moduleFile = _traceLog.ModuleFiles.Where(m => m.Name.Equals(symbolParts[0], StringComparison.OrdinalIgnoreCase)).FirstOrDefault(); if (moduleFile != null) { // Special handling for NGEN images. if (symbolParts[0].EndsWith(".ni", StringComparison.OrdinalIgnoreCase)) { SymbolReaderOptions options = _symbolReader.Options; try { _symbolReader.Options = SymbolReaderOptions.CacheOnly; _traceLog.CallStacks.CodeAddresses.LookupSymbolsForModule(_symbolReader, moduleFile); } finally { _symbolReader.Options = options; } } else { _traceLog.CallStacks.CodeAddresses.LookupSymbolsForModule(_symbolReader, moduleFile); } InvalidateCachedStructures(); } } // Mark the module as resolved so that we don't try again. _resolvedSymbolModules.Add(symbolParts[0]); // Try to get the call tree node one more time. node = FindNodeByName(Regex.Escape(symbolName)); // Check to see if the node matches. if (node.Name.StartsWith(symbolName, StringComparison.OrdinalIgnoreCase)) { return(node); } } return(null); }
public ModuleList(TraceModuleFile module, ModuleList rest) { Module = module; Next = rest; }