internal StackFrame(Thread thread, ICorDebugILFrame corILFrame, uint chainIndex, uint frameIndex) { this.process = thread.Process; this.thread = thread; this.appDomain = process.AppDomains[corILFrame.GetFunction().GetClass().GetModule().GetAssembly().GetAppDomain()]; this.corILFrame = corILFrame; this.corILFramePauseSession = process.PauseSession; this.corFunction = corILFrame.GetFunction(); this.chainIndex = chainIndex; this.frameIndex = frameIndex; MetaDataImport metaData = thread.Process.Modules[corFunction.GetClass().GetModule()].MetaData; int methodGenArgs = metaData.EnumGenericParams(corFunction.GetToken()).Length; // Class parameters are first, then the method ones List <ICorDebugType> corGenArgs = ((ICorDebugILFrame2)corILFrame).EnumerateTypeParameters().ToList(); // Remove method parametrs at the end corGenArgs.RemoveRange(corGenArgs.Count - methodGenArgs, methodGenArgs); List <DebugType> genArgs = new List <DebugType>(corGenArgs.Count); foreach (ICorDebugType corGenArg in corGenArgs) { genArgs.Add(DebugType.CreateFromCorType(this.AppDomain, corGenArg)); } DebugType debugType = DebugType.CreateFromCorClass( this.AppDomain, null, corFunction.GetClass(), genArgs.ToArray() ); this.methodInfo = (DebugMethodInfo)debugType.GetMember(corFunction.GetToken()); }
internal StackFrame(Thread thread, ICorDebugILFrame corILFrame, uint chainIndex, uint frameIndex) { this.process = thread.Process; this.thread = thread; this.appDomain = process.AppDomains[corILFrame.GetFunction().GetClass().GetModule().GetAssembly().GetAppDomain()]; this.corILFrame = corILFrame; this.corILFramePauseSession = process.PauseSession; this.corFunction = corILFrame.GetFunction(); this.chainIndex = chainIndex; this.frameIndex = frameIndex; MetaDataImport metaData = thread.Process.Modules[corFunction.GetClass().GetModule()].MetaData; int methodGenArgs = metaData.EnumGenericParams(corFunction.GetToken()).Length; // Class parameters are first, then the method ones List<ICorDebugType> corGenArgs = ((ICorDebugILFrame2)corILFrame).EnumerateTypeParameters().ToList(); // Remove method parametrs at the end corGenArgs.RemoveRange(corGenArgs.Count - methodGenArgs, methodGenArgs); List<DebugType> genArgs = new List<DebugType>(corGenArgs.Count); foreach(ICorDebugType corGenArg in corGenArgs) { genArgs.Add(DebugType.CreateFromCorType(this.AppDomain, corGenArg)); } DebugType debugType = DebugType.CreateFromCorClass( this.AppDomain, null, corFunction.GetClass(), genArgs.ToArray() ); this.methodInfo = (DebugMethodInfo)debugType.GetMember(corFunction.GetToken()); }
public static IMethod Import(this ICompilation compilation, ICorDebugFunction corFunction) { Module module = compilation.GetAppDomain().Process.GetModule(corFunction.GetModule()); if (module.IsDynamic || module.IsInMemory) { return(module.Assembly.GetTypeDefinition("", "UnknownDynamicType").Methods.First()); } var info = GetInfo(module.Assembly); uint functionToken = corFunction.GetToken(); var unresolvedMethod = info.GetMethodFromToken(functionToken); if (unresolvedMethod == null) { // The type containing this function wasn't loaded yet uint classToken = corFunction.GetClass().GetToken(); var definition = ToTypeDefinitionReference(module, classToken).Resolve(new SimpleTypeResolveContext(module.Assembly)).GetDefinition(); if (definition == null) { throw new InvalidOperationException("Could not find class for token " + classToken); } definition.Methods.ToList(); // enforce loading the methods so that they get added to the dictionary unresolvedMethod = info.GetMethodFromToken(functionToken); if (unresolvedMethod == null) { throw new InvalidOperationException("Could not find function with token " + functionToken); } } return(unresolvedMethod.Resolve(new SimpleTypeResolveContext(module.Assembly))); }
/// <summary> /// Gets the function token. /// </summary> /// <returns></returns> public UInt32 GetToken() { UInt32 token; cofunc.GetToken(out token); return(token); }
public CorFunction(ICorDebugFunction funtion) { corFunction = funtion; ICorDebugModule imodule = null; corFunction.GetModule(out imodule); module = new CorModule(imodule); corFunction.GetToken(out token); //corFunction.GetLocalVarSigToken( //ICorDebugFunctionBreakpoint breakPoint = null; //corFunction. }
/// <summary> /// Finds appropriete SequncePointMap instances and builds SequencePointRemapper, gets new IL offset and call RemapFunction. /// </summary> public void FunctionRemapOpportunity(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pOldFunction, ICorDebugFunction pNewFunction, uint oldILOffset) { ICorDebugILFrame2 frame = (ICorDebugILFrame2) pThread.GetActiveFrame(); uint nToken = pOldFunction.GetToken(); SequencePointRemapper remapper; if(!remappers.TryGetValue(nToken,out remapper)){ throw new KeyNotFoundException("Methods sequence points not found."); } frame.__RemapFunction(remapper.TranslateILOffset(oldILOffset)); }
/// <summary> /// Finds appropriete SequncePointMap instances and builds SequencePointRemapper, gets new IL offset and call RemapFunction. /// </summary> public void FunctionRemapOpportunity(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugFunction pOldFunction, ICorDebugFunction pNewFunction, uint oldILOffset) { ICorDebugILFrame2 frame = (ICorDebugILFrame2)pThread.GetActiveFrame(); uint nToken = pOldFunction.GetToken(); SequencePointRemapper remapper; if (!remappers.TryGetValue(nToken, out remapper)) { throw new KeyNotFoundException("Methods sequence points not found."); } frame.__RemapFunction(remapper.TranslateILOffset(oldILOffset)); }
/// <summary> /// 'ILStart <= ILOffset <= ILEnd' and this range includes at least /// the returned area of source code. (May incude some extra compiler generated IL too) /// </summary> internal static SourcecodeSegment Resolve(Module module, ICorDebugFunction corFunction, int offset) { ISymUnmanagedReader symReader = module.SymReader; if (symReader == null) return null; // No symbols ISymUnmanagedMethod symMethod; try { symMethod = symReader.GetMethod(corFunction.GetToken()); } catch (COMException) { // Can not find the method // eg. Compiler generated constructors are not in symbol store return null; } if (symMethod == null) return null; uint sequencePointCount = symMethod.GetSequencePointCount(); SequencePoint[] sequencePoints = symMethod.GetSequencePoints(); // Get i for which: offsets[i] <= offset < offsets[i + 1] // or fallback to first element if offset < offsets[0] for (int i = (int)sequencePointCount - 1; i >= 0; i--) { // backwards if ((int)sequencePoints[i].Offset <= offset || i == 0) { // Set inforamtion about current IL range int codeSize = (int)corFunction.GetILCode().GetSize(); int ilStart = (int)sequencePoints[i].Offset; int ilEnd = (i + 1 < sequencePointCount) ? (int)sequencePoints[i+1].Offset : codeSize; // 0xFeeFee means "code generated by compiler" // If we are in generated sequence use to closest real one instead, // extend the ILStart and ILEnd to include the 'real' sequence // Look ahead for 'real' sequence while (i + 1 < sequencePointCount && sequencePoints[i].Line == 0xFeeFee) { i++; ilEnd = (i + 1 < sequencePointCount) ? (int)sequencePoints[i+1].Offset : codeSize; } // Look back for 'real' sequence while (i - 1 >= 0 && sequencePoints[i].Line == 0xFeeFee) { i--; ilStart = (int)sequencePoints[i].Offset; } // Wow, there are no 'real' sequences if (sequencePoints[i].Line == 0xFeeFee) { return null; } List<int> stepRanges = new List<int>(); for (int j = 0; j < sequencePointCount; j++) { // Step over compiler generated sequences and current statement // 0xFeeFee means "code generated by compiler" if (sequencePoints[j].Line == 0xFeeFee || j == i) { // Add start offset or remove last end (to connect two ranges into one) if (stepRanges.Count > 0 && stepRanges[stepRanges.Count - 1] == sequencePoints[j].Offset) { stepRanges.RemoveAt(stepRanges.Count - 1); } else { stepRanges.Add((int)sequencePoints[j].Offset); } // Add end offset | handle last sequence point if (j + 1 < sequencePointCount) { stepRanges.Add((int)sequencePoints[j+1].Offset); } else { stepRanges.Add(codeSize); } } } SourcecodeSegment segment = new SourcecodeSegment(); segment.module = module; segment.filename = GetFilenameFromSymDocument(module, sequencePoints[i].Document); segment.checkSum = sequencePoints[i].Document.GetCheckSum(); segment.startLine = (int)sequencePoints[i].Line; segment.startColumn = (int)sequencePoints[i].Column; segment.endLine = (int)sequencePoints[i].EndLine; segment.endColumn = (int)sequencePoints[i].EndColumn; segment.corFunction = corFunction; segment.ilStart = ilStart; segment.ilEnd = ilEnd; segment.stepRanges = stepRanges.ToArray(); // VB.NET sometimes produces temporary files which it then deletes // (eg 17d14f5c-a337-4978-8281-53493378c1071.vb) string filename = Path.GetFileName(segment.filename); if (filename.Length == 40 && filename.EndsWith(".vb")) { bool guidName = true; foreach(char c in filename.Substring(0, filename.Length - 3)) { if (('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F') || (c == '-')) { guidName = true; } else { guidName = false; break; } } if (guidName) return null; } return segment; } } return null; }
/// <summary> /// 'ILStart <= ILOffset <= ILEnd' and this range includes at least /// the returned area of source code. (May incude some extra compiler generated IL too) /// </summary> internal static SourcecodeSegment Resolve(Module module, ICorDebugFunction corFunction, int offset) { ISymUnmanagedReader symReader = module.SymReader; if (symReader == null) { return(null); // No symbols } ISymUnmanagedMethod symMethod; try { symMethod = symReader.GetMethod(corFunction.GetToken()); } catch (COMException) { // Can not find the method // eg. Compiler generated constructors are not in symbol store return(null); } if (symMethod == null) { return(null); } uint sequencePointCount = symMethod.GetSequencePointCount(); SequencePoint[] sequencePoints = symMethod.GetSequencePoints(); // Get i for which: offsets[i] <= offset < offsets[i + 1] // or fallback to first element if offset < offsets[0] for (int i = (int)sequencePointCount - 1; i >= 0; i--) // backwards { if ((int)sequencePoints[i].Offset <= offset || i == 0) { // Set inforamtion about current IL range int codeSize = (int)corFunction.GetILCode().GetSize(); int ilStart = (int)sequencePoints[i].Offset; int ilEnd = (i + 1 < sequencePointCount) ? (int)sequencePoints[i + 1].Offset : codeSize; // 0xFeeFee means "code generated by compiler" // If we are in generated sequence use to closest real one instead, // extend the ILStart and ILEnd to include the 'real' sequence // Look ahead for 'real' sequence while (i + 1 < sequencePointCount && sequencePoints[i].Line == 0xFeeFee) { i++; ilEnd = (i + 1 < sequencePointCount) ? (int)sequencePoints[i + 1].Offset : codeSize; } // Look back for 'real' sequence while (i - 1 >= 0 && sequencePoints[i].Line == 0xFeeFee) { i--; ilStart = (int)sequencePoints[i].Offset; } // Wow, there are no 'real' sequences if (sequencePoints[i].Line == 0xFeeFee) { return(null); } List <int> stepRanges = new List <int>(); for (int j = 0; j < sequencePointCount; j++) { // Step over compiler generated sequences and current statement // 0xFeeFee means "code generated by compiler" if (sequencePoints[j].Line == 0xFeeFee || j == i) { // Add start offset or remove last end (to connect two ranges into one) if (stepRanges.Count > 0 && stepRanges[stepRanges.Count - 1] == sequencePoints[j].Offset) { stepRanges.RemoveAt(stepRanges.Count - 1); } else { stepRanges.Add((int)sequencePoints[j].Offset); } // Add end offset | handle last sequence point if (j + 1 < sequencePointCount) { stepRanges.Add((int)sequencePoints[j + 1].Offset); } else { stepRanges.Add(codeSize); } } } SourcecodeSegment segment = new SourcecodeSegment(); segment.module = module; segment.filename = GetFilenameFromSymDocument(module, sequencePoints[i].Document); segment.checkSum = sequencePoints[i].Document.GetCheckSum(); segment.startLine = (int)sequencePoints[i].Line; segment.startColumn = (int)sequencePoints[i].Column; segment.endLine = (int)sequencePoints[i].EndLine; segment.endColumn = (int)sequencePoints[i].EndColumn; segment.corFunction = corFunction; segment.ilStart = ilStart; segment.ilEnd = ilEnd; segment.stepRanges = stepRanges.ToArray(); // VB.NET sometimes produces temporary files which it then deletes // (eg 17d14f5c-a337-4978-8281-53493378c1071.vb) string filename = Path.GetFileName(segment.filename); if (filename.Length == 40 && filename.EndsWith(".vb")) { bool guidName = true; foreach (char c in filename.Substring(0, filename.Length - 3)) { if (('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F') || (c == '-')) { guidName = true; } else { guidName = false; break; } } if (guidName) { return(null); } } return(segment); } } return(null); }
public static IMethod Import(this ICompilation compilation, ICorDebugFunction corFunction) { Module module = compilation.GetAppDomain().Process.GetModule(corFunction.GetModule()); if (module.IsDynamic || module.IsInMemory) { return module.Assembly.GetTypeDefinition("", "UnknownDynamicType").Methods.First(); } var info = GetInfo(module.Assembly); uint functionToken = corFunction.GetToken(); var unresolvedMethod = info.GetMethodFromToken(functionToken); if (unresolvedMethod == null) { // The type containing this function wasn't loaded yet uint classToken = corFunction.GetClass().GetToken(); var definition = ToTypeDefinitionReference(module, classToken).Resolve(new SimpleTypeResolveContext(module.Assembly)).GetDefinition(); if (definition == null) throw new InvalidOperationException("Could not find class for token " + classToken); definition.Methods.ToList(); // enforce loading the methods so that they get added to the dictionary unresolvedMethod = info.GetMethodFromToken(functionToken); if (unresolvedMethod == null) throw new InvalidOperationException("Could not find function with token " + functionToken); } return unresolvedMethod.Resolve(new SimpleTypeResolveContext(module.Assembly)); }