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); }
// TODO is making this public a hack? public StackSourceFrameIndex GetFrameIndex(CodeAddressIndex codeAddressIndex, out bool isReasonableTopStack) { isReasonableTopStack = false; string moduleName = "?"; ModuleFileIndex moduleIdx = m_log.CodeAddresses.ModuleFileIndex(codeAddressIndex); if (moduleIdx != Diagnostics.Tracing.ModuleFileIndex.Invalid) { moduleName = m_log.ModuleFiles[moduleIdx].FilePath; if (moduleName.EndsWith("ntdll.dll", StringComparison.OrdinalIgnoreCase)) { isReasonableTopStack = true; } } var internedModule = Interner.ModuleIntern(moduleName); string methodName = "?"; var methodIdx = m_log.CodeAddresses.MethodIndex(codeAddressIndex); if (methodIdx != MethodIndex.Invalid) { methodName = m_log.CodeAddresses.Methods.FullMethodName(methodIdx); } else if (ShowUnknownAddressses) { methodName = "0x" + m_log.CallStacks.CodeAddresses.Address(codeAddressIndex).ToString("x"); } var internedFrame = Interner.FrameIntern(methodName, internedModule); return(internedFrame); }
/// <summary> /// Given a thread and a call stack that does not have a stack, make up a pseudo stack for it consisting of the code address, /// the broken node, the thread and process. Will return -1 if it can't allocate another Pseudo-stack. /// </summary> private int GetPseudoStack(ThreadIndex threadIndex, CodeAddressIndex codeAddrIndex) { if (m_pseudoStacksTable == null) { m_pseudoStacksTable = new Dictionary <PseudoStack, int>(); } var pseudoStack = new PseudoStack(threadIndex, codeAddrIndex); int ret; if (m_pseudoStacksTable.TryGetValue(pseudoStack, out ret)) { return(ret); } ret = m_pseudoStacks.Count; if (ret >= m_maxPseudoStack) { return(-1); } m_pseudoStacks.Add(pseudoStack); m_pseudoStacksTable.Add(pseudoStack, ret); return(ret); }
private StackSourceCallStackIndex GetStack(TraceEvent event_) { // Console.WriteLine("Getting Stack for sample at {0:f4}", sample.TimeStampRelativeMSec); int ret = (int)event_.CallStackIndex(); if (ret == (int)CallStackIndex.Invalid) { var thread = event_.Thread(); if (thread == null) { return(StackSourceCallStackIndex.Invalid); } // If the event is a sample profile, or page fault we can make a one element stack with the EIP in the event CodeAddressIndex codeAddrIdx = CodeAddressIndex.Invalid; var asSampleProfile = event_ as SampledProfileTraceData; if (asSampleProfile != null) { codeAddrIdx = asSampleProfile.IntructionPointerCodeAddressIndex(); } else { var asPageFault = event_ as MemoryHardFaultTraceData; if (asPageFault != null) { codeAddrIdx = asSampleProfile.IntructionPointerCodeAddressIndex(); } } if (codeAddrIdx != CodeAddressIndex.Invalid) { // Encode the code address for the given thread. int pseudoStackIndex = GetPseudoStack(thread.ThreadIndex, codeAddrIdx); // Psuedostacks happen after all the others. if (0 <= pseudoStackIndex) { ret = m_log.CallStacks.Count + 2 * m_log.Threads.Count + m_log.Processes.Count + pseudoStackIndex; } } // If we have run out of pseudo-stacks, we encode the stack as being at the thread. if (ret == (int)CallStackIndex.Invalid) { ret = m_log.CallStacks.Count + (int)thread.ThreadIndex; } } else { // We expect the thread we get when looking at the CallStack to match the thread of the event. Debug.Assert(m_log.CallStacks.Thread((CallStackIndex)ret).ThreadID == event_.ThreadID); Debug.Assert(event_.Thread().Process.ProcessID == event_.ProcessID); } ret = ret + (int)StackSourceCallStackIndex.Start; return((StackSourceCallStackIndex)ret); }
private StackSourceCallStackIndex GetStack(TraceEvent event_) { // Console.WriteLine("Getting Stack for sample at {0:f4}", sample.TimeStampRelativeMSec); var ret = (int)event_.CallStackIndex(); if (ret == (int)CallStackIndex.Invalid) { var thread = event_.Thread(); if (thread == null) { return(StackSourceCallStackIndex.Invalid); } // If the event is a sample profile, or page fault we can make a one element stack with the EIP in the event CodeAddressIndex codeAddrIdx = CodeAddressIndex.Invalid; var asSampleProfile = event_ as SampledProfileTraceData; if (asSampleProfile != null) { codeAddrIdx = asSampleProfile.IntructionPointerCodeAddressIndex(); } else { var asPageFault = event_ as PageFaultHardFaultTraceData; if (asPageFault != null) { codeAddrIdx = asSampleProfile.IntructionPointerCodeAddressIndex(); } } if (codeAddrIdx != CodeAddressIndex.Invalid) { // Encode the code address for the given thread. int pseudoStackIndex = GetPseudoStack(thread.ThreadIndex, codeAddrIdx); if (pseudoStackIndex < 0) { return(StackSourceCallStackIndex.Start); } // Psuedostacks happen after all the others. ret = m_log.CallStacks.MaxCallStackIndex + 2 * m_log.Threads.MaxThreadIndex + m_log.Processes.MaxProcessIndex + pseudoStackIndex; } else { // Otherwise we encode the stack as being at the thread. ret = m_log.CallStacks.MaxCallStackIndex + (int)thread.ThreadIndex; } } ret = ret + (int)StackSourceCallStackIndex.Start; return((StackSourceCallStackIndex)ret); }
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> /// Implementation of StackSource protocol. /// </summary> public override StackSourceFrameIndex GetFrameIndex(StackSourceCallStackIndex callStackIndex) { Debug.Assert(callStackIndex >= 0); Debug.Assert(StackSourceCallStackIndex.Start == 0); // If there are any cases before start, we need to handle them here. int stackIndex = (int)callStackIndex - (int)StackSourceCallStackIndex.Start; if (stackIndex < m_log.CallStacks.Count) { CodeAddressIndex codeAddressIndex = m_log.CallStacks.CodeAddressIndex((CallStackIndex)stackIndex); return((StackSourceFrameIndex)(codeAddressIndex + (int)StackSourceFrameIndex.Start)); } stackIndex -= m_log.CallStacks.Count; if (stackIndex < m_log.Threads.Count + m_log.Processes.Count) { // At this point this is the encoded thread/process index. We use the same encoding for both stacks and for frame names // so we just need to add back in the proper offset. return((StackSourceFrameIndex)(stackIndex + m_log.CodeAddresses.Count + (int)StackSourceFrameIndex.Start)); } stackIndex -= m_log.Threads.Count + m_log.Processes.Count; if (stackIndex < m_log.Threads.Count) // Is it a broken stack { return(StackSourceFrameIndex.Broken); } stackIndex -= m_log.Threads.Count; // Is it a 'single node' stack (e.g. a profile sample without a stack) if (stackIndex < m_pseudoStacks.Count) { // From the Pseudo stack index, find the code address. int codeAddressIndex = (int)m_pseudoStacks[stackIndex].CodeAddressIndex; // Return it as the frame. return((StackSourceFrameIndex)(codeAddressIndex + (int)StackSourceFrameIndex.Start)); } Debug.Assert(false, "Illegal Call Stack Index"); return(StackSourceFrameIndex.Invalid); }
public PseudoStack(ThreadIndex threadIndex, CodeAddressIndex codeAddressIndex) { ThreadIndex = threadIndex; CodeAddressIndex = codeAddressIndex; }
/// <summary> /// Create a frame name from a TraceEvent code address. /// </summary> public StackSourceFrameIndex GetFrameIndex(CodeAddressIndex codeAddressIndex) { return((StackSourceFrameIndex)((int)StackSourceFrameIndex.Start + (int)codeAddressIndex)); }