Example #1
0
        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);
        }
Example #2
0
        // 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);
        }
Example #3
0
        /// <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);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
        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);
        }
Example #7
0
        /// <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);
        }
Example #8
0
 public PseudoStack(ThreadIndex threadIndex, CodeAddressIndex codeAddressIndex)
 {
     ThreadIndex = threadIndex; CodeAddressIndex = codeAddressIndex;
 }
Example #9
0
 /// <summary>
 /// Create a frame name from a TraceEvent code address.
 /// </summary>
 public StackSourceFrameIndex GetFrameIndex(CodeAddressIndex codeAddressIndex)
 {
     return((StackSourceFrameIndex)((int)StackSourceFrameIndex.Start + (int)codeAddressIndex));
 }