internal ICorDebugFrame GetFrameAt(FrameID frameID) { process.AssertPaused(); ICorDebugChainEnum corChainEnum = CorThread.EnumerateChains(); if (frameID.ChainIndex >= corChainEnum.Count) { throw new ArgumentException("Chain index too big", "chainIndex"); } corChainEnum.Skip(corChainEnum.Count - frameID.ChainIndex - 1); ICorDebugChain corChain = corChainEnum.Next(); if (corChain.IsManaged == 0) { throw new ArgumentException("Chain is not managed", "chainIndex"); } ICorDebugFrameEnum corFrameEnum = corChain.EnumerateFrames(); if (frameID.FrameIndex >= corFrameEnum.Count) { throw new ArgumentException("Frame index too big", "frameIndex"); } corFrameEnum.Skip(corFrameEnum.Count - frameID.FrameIndex - 1); return(corFrameEnum.Next()); }
public static ICorDebugFrame Next(this ICorDebugFrameEnum corEnum) { ICorDebugFrame[] corFrames = new ICorDebugFrame[] { null }; uint framesFetched = corEnum.Next(1, corFrames); return(corFrames[0]); }
// ICorDebugEnum public static IEnumerable <ICorDebugFrame> GetEnumerator(this ICorDebugFrameEnum corEnum) { corEnum.Reset(); while (true) { ICorDebugFrame[] corFrames = new ICorDebugFrame[EnumerateBufferSize]; uint fetched = corEnum.Next(EnumerateBufferSize, corFrames); if (fetched == 0) { yield break; } for (int i = 0; i < fetched; i++) { yield return(corFrames[i]); } } }
int ICorDebugChain.EnumerateFrames(out ICorDebugFrameEnum ppFrames) { //Reverse the order for the enumerator CorDebugFrame[] frames = new CorDebugFrame[m_frames.Length]; int iFrameSrc = m_frames.Length - 1; for (int iFrameDst = 0; iFrameDst < m_frames.Length; iFrameDst++) { frames[iFrameDst] = m_frames[iFrameSrc]; iFrameSrc--; } ppFrames = new CorDebugEnum(frames, typeof(ICorDebugFrame), typeof(ICorDebugFrameEnum)); return(COM_HResults.S_OK); }
internal StackFrame GetStackFrameAt(uint chainIndex, uint frameIndex) { process.AssertPaused(); ICorDebugChainEnum corChainEnum = CorThread.EnumerateChains(); if (chainIndex >= corChainEnum.GetCount()) { throw new DebuggerException("The requested chain index is too big"); } corChainEnum.Skip(corChainEnum.GetCount() - chainIndex - 1); ICorDebugChain corChain = corChainEnum.Next(); if (corChain.IsManaged() == 0) { throw new DebuggerException("The requested chain is not managed"); } ICorDebugFrameEnum corFrameEnum = corChain.EnumerateFrames(); if (frameIndex >= corFrameEnum.GetCount()) { throw new DebuggerException("The requested frame index is too big"); } corFrameEnum.Skip(corFrameEnum.GetCount() - frameIndex - 1); ICorDebugFrame corFrame = corFrameEnum.Next(); if (!(corFrame is ICorDebugILFrame)) { throw new DebuggerException("The rquested frame is not IL frame"); } StackFrame stackFrame = new StackFrame(this, (ICorDebugILFrame)corFrame, chainIndex, frameIndex); return(stackFrame); }
internal CorFrameEnumerator(ICorDebugFrameEnum frameEnumerator) { m_enum = frameEnumerator; }
// See docs\Stepping.txt public void CheckExpiration() { try { ICorDebugChainEnum chainEnum = CorThread.EnumerateChains(); } catch (COMException e) { // 0x8013132D: The state of the thread is invalid. // 0x8013134F: Object is in a zombie state // 0x80131301: Process was terminated. if ((uint)e.ErrorCode == 0x8013132D || (uint)e.ErrorCode == 0x8013134F || (uint)e.ErrorCode == 0x80131301) { this.Expire(); return; } else { throw; } } if (process.Evaluating) { return; } ICorDebugChainEnum corChainEnum = CorThread.EnumerateChains(); int maxChainIndex = (int)corChainEnum.Count - 1; ICorDebugFrameEnum corFrameEnum = corChainEnum.Next().EnumerateFrames(); // corFrameEnum.Count can return 0 in ExitThread callback int maxFrameIndex = (int)corFrameEnum.Count - 1; ICorDebugFrame lastFrame = corFrameEnum.Next(); // Check the token of the current function - function can change if there are multiple handlers for an event Function function; if (lastFrame != null && functionCache.TryGetValue(new FrameID((uint)maxChainIndex, (uint)maxFrameIndex), out function) && function.Token != lastFrame.FunctionToken) { functionCache.Remove(new FrameID((uint)maxChainIndex, (uint)maxFrameIndex)); function.OnExpired(EventArgs.Empty); } // Expire all functions behind the current maximum // Multiple functions can expire at once (test case: Step out of Button1Click in simple winforms application) List <KeyValuePair <FrameID, Function> > toBeRemoved = new List <KeyValuePair <FrameID, Function> >(); foreach (KeyValuePair <FrameID, Function> kvp in functionCache) { if ((kvp.Key.ChainIndex > maxChainIndex) || (kvp.Key.ChainIndex == maxChainIndex && kvp.Key.FrameIndex > maxFrameIndex)) { toBeRemoved.Add(kvp); } } foreach (KeyValuePair <FrameID, Function> kvp in toBeRemoved) { functionCache.Remove(kvp.Key); kvp.Value.OnExpired(EventArgs.Empty); } }
int ICorDebugChain. EnumerateFrames( out ICorDebugFrameEnum ppFrames ) { //Reverse the order for the enumerator CorDebugFrame[] frames = new CorDebugFrame[m_frames.Length]; int iFrameSrc = m_frames.Length - 1; for(int iFrameDst = 0; iFrameDst < m_frames.Length; iFrameDst++) { frames[iFrameDst] = m_frames[iFrameSrc]; iFrameSrc--; } ppFrames = new CorDebugEnum( frames, typeof( ICorDebugFrame ), typeof( ICorDebugFrameEnum ) ); return Utility.COM_HResults.S_OK; }