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()); }
Function GetFunctionFromCache(FrameID frameID, ICorDebugILFrame corFrame) { Function function; if (functionCache.TryGetValue(frameID, out function) && !function.HasExpired) { function.CorILFrame = corFrame; return(function); } else { function = new Function(this, frameID, corFrame); functionCache[frameID] = function; return(function); } }
internal Function(Thread thread, FrameID frameID, ICorDebugILFrame corILFrame) { this.process = thread.Process; this.thread = thread; this.frameID = frameID; this.CorILFrame = corILFrame; corFunction = corILFrame.Function; module = process.GetModule(corFunction.Module); methodProps = module.MetaData.GetMethodProps(corFunction.Token); // Force some callback when function steps out so that we can expire it stepOutStepper = new Stepper(this, "Function Tracker"); stepOutStepper.StepOut(); stepOutStepper.PauseWhenComplete = false; process.TraceMessage("Function " + this.ToString() + " created"); }