public MethodDebugInformation Read(MethodDefinition method) { var method_token = method.MetadataToken; PdbFunction function; if (!functions.TryGetValue(method_token.ToUInt32(), out function)) { return(null); } var symbol = new MethodDebugInformation(method); ReadSequencePoints(function, symbol); symbol.scope = !function.scopes.IsNullOrEmpty() ? ReadScopeAndLocals(function.scopes [0], symbol) : new ScopeDebugInformation { Start = new InstructionOffset(0), End = new InstructionOffset((int)function.length) }; if (function.tokenOfMethodWhoseUsingInfoAppliesToThisMethod != method.MetadataToken.ToUInt32() && function.tokenOfMethodWhoseUsingInfoAppliesToThisMethod != 0) { symbol.scope.import = GetImport(function.tokenOfMethodWhoseUsingInfoAppliesToThisMethod, method.Module); } if (function.scopes.Length > 1) { for (int i = 1; i < function.scopes.Length; i++) { var s = ReadScopeAndLocals(function.scopes [i], symbol); if (!AddScope(symbol.scope.Scopes, s)) { symbol.scope.Scopes.Add(s); } } } if (function.iteratorScopes != null) { var state_machine = new StateMachineScopeDebugInformation(); foreach (var iterator_scope in function.iteratorScopes) { state_machine.Scopes.Add(new StateMachineScope((int)iterator_scope.Offset, (int)(iterator_scope.Offset + iterator_scope.Length + 1))); } symbol.CustomDebugInformations.Add(state_machine); } if (function.synchronizationInformation != null) { var async_debug_info = new AsyncMethodBodyDebugInformation((int)function.synchronizationInformation.GeneratedCatchHandlerOffset); foreach (var synchronization_point in function.synchronizationInformation.synchronizationPoints) { async_debug_info.Yields.Add(new InstructionOffset((int)synchronization_point.SynchronizeOffset)); async_debug_info.Resumes.Add(new InstructionOffset((int)synchronization_point.ContinuationOffset)); async_debug_info.ResumeMethods.Add(method); } symbol.CustomDebugInformations.Add(async_debug_info); symbol.StateMachineKickOffMethod = (MethodDefinition)method.Module.LookupToken((int)function.synchronizationInformation.kickoffMethodToken); } return(symbol); }
ScopeDebugInformation ReadScopeAndLocals(PdbScope scope, MethodDebugInformation info) { var parent = new ScopeDebugInformation(); parent.Start = new InstructionOffset((int)scope.offset); parent.End = new InstructionOffset((int)(scope.offset + scope.length)); if (!scope.slots.IsNullOrEmpty()) { parent.variables = new Collection <VariableDebugInformation> (scope.slots.Length); foreach (PdbSlot slot in scope.slots) { if (slot.flags == 1) // parameter names { continue; } var index = (int)slot.slot; var variable = new VariableDebugInformation(index, slot.name); if (slot.flags == 4) { variable.IsDebuggerHidden = true; } parent.variables.Add(variable); } } if (!scope.constants.IsNullOrEmpty()) { parent.constants = new Collection <ConstantDebugInformation> (scope.constants.Length); foreach (var constant in scope.constants) { var type = info.Method.Module.Read(constant, (c, r) => r.ReadConstantSignature(new MetadataToken(c.token))); var value = constant.value; // Object "null" is encoded as integer if (type != null && !type.IsValueType && value is int && (int)value == 0) { value = null; } parent.constants.Add(new ConstantDebugInformation(constant.name, type, value)); } } if (!scope.usedNamespaces.IsNullOrEmpty()) { ImportDebugInformation import; if (imports.TryGetValue(scope, out import)) { parent.import = import; } else { import = GetImport(scope, info.Method.Module); imports.Add(scope, import); parent.import = import; } } parent.scopes = ReadScopeAndLocals(scope.scopes, info); return(parent); }
public void Write(MethodDebugInformation info) => throw new NotImplementedException();
public static void Generate(DynamicMethodDefinition dmd, MethodBase _mb, ILGenerator il) { MethodDefinition def = dmd.Definition; DynamicMethod dm = _mb as DynamicMethod; #if !NETSTANDARD MethodBuilder mb = _mb as MethodBuilder; ModuleBuilder moduleBuilder = mb?.Module as ModuleBuilder; // moduleBuilder.Assembly sometimes avoids the .Assembly override under mysterious circumstances. AssemblyBuilder assemblyBuilder = (mb?.DeclaringType as TypeBuilder)?.Assembly as AssemblyBuilder; HashSet <Assembly> accessChecksIgnored = null; if (mb != null) { accessChecksIgnored = new HashSet <Assembly>(); } #endif #if !CECIL0_9 MethodDebugInformation defInfo = dmd.Debug ? def.DebugInformation : null; #endif if (dm != null) { foreach (ParameterDefinition param in def.Parameters) { dm.DefineParameter(param.Index + 1, (System.Reflection.ParameterAttributes)param.Attributes, param.Name); } } #if !NETSTANDARD if (mb != null) { foreach (ParameterDefinition param in def.Parameters) { mb.DefineParameter(param.Index + 1, (System.Reflection.ParameterAttributes)param.Attributes, param.Name); } } #endif LocalBuilder[] locals = def.Body.Variables.Select( var => { LocalBuilder local = il.DeclareLocal(var.VariableType.ResolveReflection(), var.IsPinned); #if !NETSTANDARD && !CECIL0_9 if (mb != null && defInfo != null && defInfo.TryGetName(var, out string name)) { local.SetLocalSymInfo(name); } #endif return(local); } ).ToArray(); // Pre-pass - Set up label map. Dictionary <Instruction, Label> labelMap = new Dictionary <Instruction, Label>(); foreach (Instruction instr in def.Body.Instructions) { if (instr.Operand is Instruction[] targets) { foreach (Instruction target in targets) { if (!labelMap.ContainsKey(target)) { labelMap[target] = il.DefineLabel(); } } } else if (instr.Operand is Instruction target) { if (!labelMap.ContainsKey(target)) { labelMap[target] = il.DefineLabel(); } } } #if !NETSTANDARD && !CECIL0_9 Dictionary <Document, ISymbolDocumentWriter> infoDocCache = mb == null ? null : new Dictionary <Document, ISymbolDocumentWriter>(); #endif int paramOffs = def.HasThis ? 1 : 0; object[] emitArgs = new object[2]; bool checkTryEndEarly = false; foreach (Instruction instr in def.Body.Instructions) { if (labelMap.TryGetValue(instr, out Label label)) { il.MarkLabel(label); } #if !NETSTANDARD && !CECIL0_9 SequencePoint instrInfo = defInfo?.GetSequencePoint(instr); if (mb != null && instrInfo != null) { if (!infoDocCache.TryGetValue(instrInfo.Document, out ISymbolDocumentWriter infoDoc)) { infoDocCache[instrInfo.Document] = infoDoc = moduleBuilder.DefineDocument( instrInfo.Document.Url, instrInfo.Document.LanguageGuid, instrInfo.Document.LanguageVendorGuid, instrInfo.Document.TypeGuid ); } il.MarkSequencePoint(infoDoc, instrInfo.StartLine, instrInfo.StartColumn, instrInfo.EndLine, instrInfo.EndColumn); } #endif foreach (ExceptionHandler handler in def.Body.ExceptionHandlers) { if (checkTryEndEarly && handler.HandlerEnd == instr) { il.EndExceptionBlock(); } if (handler.TryStart == instr) { il.BeginExceptionBlock(); } else if (handler.FilterStart == instr) { il.BeginExceptFilterBlock(); } else if (handler.HandlerStart == instr) { switch (handler.HandlerType) { case ExceptionHandlerType.Filter: il.BeginCatchBlock(null); break; case ExceptionHandlerType.Catch: il.BeginCatchBlock(handler.CatchType.ResolveReflection()); break; case ExceptionHandlerType.Finally: il.BeginFinallyBlock(); break; case ExceptionHandlerType.Fault: il.BeginFaultBlock(); break; } } // Avoid duplicate endfilter / endfinally if (handler.HandlerStart == instr.Next) { switch (handler.HandlerType) { case ExceptionHandlerType.Filter: if (instr.OpCode == Mono.Cecil.Cil.OpCodes.Endfilter) { goto SkipEmit; } break; case ExceptionHandlerType.Finally: if (instr.OpCode == Mono.Cecil.Cil.OpCodes.Endfinally) { goto SkipEmit; } break; } } } if (instr.OpCode.OperandType == Mono.Cecil.Cil.OperandType.InlineNone) { il.Emit(_ReflOpCodes[instr.OpCode.Value]); } else { object operand = instr.Operand; if (operand is Instruction[] targets) { operand = targets.Select(target => labelMap[target]).ToArray(); // Let's hope that the JIT treats the long forms identically to the short forms. instr.OpCode = instr.OpCode.ToLongOp(); } else if (operand is Instruction target) { operand = labelMap[target]; // Let's hope that the JIT treats the long forms identically to the short forms. instr.OpCode = instr.OpCode.ToLongOp(); } else if (operand is VariableDefinition var) { operand = locals[var.Index]; } else if (operand is ParameterDefinition param) { operand = param.Index + paramOffs; } else if (operand is MemberReference mref) { MemberInfo member = mref.ResolveReflection(); operand = member; #if !NETSTANDARD if (mb != null && member != null) { Assembly asm = member.Module?.Assembly; if (asm != null && !accessChecksIgnored.Contains(asm)) { // while (member.DeclaringType != null) // member = member.DeclaringType; assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(DynamicMethodDefinition.c_IgnoresAccessChecksToAttribute, new object[] { asm.GetName().Name })); accessChecksIgnored.Add(asm); } } #endif } else if (operand is CallSite csite) { if (dm != null) { // SignatureHelper in unmanaged contexts cannot be fully made use of for DynamicMethods. _EmitCallSite(dm, il, _ReflOpCodes[instr.OpCode.Value], csite); continue; } #if !NETSTANDARD operand = csite.ResolveReflection(mb.Module); #else throw new NotSupportedException(); #endif } #if !NETSTANDARD if (mb != null && operand is MethodBase called && called.DeclaringType == null) { // "Global" methods (f.e. DynamicMethods) cannot be tokenized. if (instr.OpCode == Mono.Cecil.Cil.OpCodes.Call) { if (operand is DynamicMethod target) { // This should be heavily optimizable. operand = _CreateMethodProxy(mb, target); } else { IntPtr ptr = called.GetLdftnPointer(); if (IntPtr.Size == 4) { il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)ptr); } else { il.Emit(System.Reflection.Emit.OpCodes.Ldc_I8, (long)ptr); } il.Emit(System.Reflection.Emit.OpCodes.Conv_I); instr.OpCode = Mono.Cecil.Cil.OpCodes.Calli; operand = ((MethodReference)instr.Operand).ResolveReflectionSignature(mb.Module); } } else { throw new NotSupportedException($"Unsupported global method operand on opcode {instr.OpCode.Name}"); } } #endif if (operand == null) { throw new NullReferenceException($"Unexpected null in {def} @ {instr}"); } il.DynEmit(_ReflOpCodes[instr.OpCode.Value], operand); } if (!checkTryEndEarly) { foreach (ExceptionHandler handler in def.Body.ExceptionHandlers) { if (handler.HandlerEnd == instr.Next) { il.EndExceptionBlock(); } } } checkTryEndEarly = false; continue; SkipEmit: checkTryEndEarly = true; continue; } }
void DefineScope(ScopeDebugInformation scope, MethodDebugInformation info, out MetadataToken import_parent) { var start_offset = scope.Start.Offset; var end_offset = scope.End.IsEndOfMethod ? info.code_size : scope.End.Offset; import_parent = new MetadataToken(0u); writer.OpenScope(start_offset); if (scope.Import != null && scope.Import.HasTargets && !import_info_to_parent.TryGetValue(info.scope.Import, out import_parent)) { foreach (var target in scope.Import.Targets) { switch (target.Kind) { case ImportTargetKind.ImportNamespace: writer.UsingNamespace("U" + target.@namespace); break; case ImportTargetKind.ImportType: writer.UsingNamespace("T" + TypeParser.ToParseable(target.type)); break; case ImportTargetKind.DefineNamespaceAlias: writer.UsingNamespace("A" + target.Alias + " U" + target.@namespace); break; case ImportTargetKind.DefineTypeAlias: writer.UsingNamespace("A" + target.Alias + " T" + TypeParser.ToParseable(target.type)); break; } } import_info_to_parent.Add(info.scope.Import, info.method.MetadataToken); } var sym_token = info.local_var_token.ToInt32(); if (!scope.variables.IsNullOrEmpty()) { for (int i = 0; i < scope.variables.Count; i++) { var variable = scope.variables [i]; DefineLocalVariable(variable, sym_token, start_offset, end_offset); } } if (!scope.constants.IsNullOrEmpty()) { for (int i = 0; i < scope.constants.Count; i++) { var constant = scope.constants [i]; DefineConstant(constant); } } if (!scope.scopes.IsNullOrEmpty()) { for (int i = 0; i < scope.scopes.Count; i++) { MetadataToken _; DefineScope(scope.scopes [i], info, out _); } } writer.CloseScope(end_offset); }
public void CompileMethod(CppMethodCodeNode methodCodeNodeNeedingCode) { MethodDesc method = methodCodeNodeNeedingCode.Method; _compilation.Log.WriteLine("Compiling " + method.ToString()); if (method.HasCustomAttribute("System.Runtime", "RuntimeImportAttribute")) { CompileExternMethod(methodCodeNodeNeedingCode, ((EcmaMethod)method).GetRuntimeImportName()); return; } if (method.IsRawPInvoke()) { CompileExternMethod(methodCodeNodeNeedingCode, method.GetPInvokeMethodMetadata().Name ?? method.Name); return; } var methodIL = _compilation.GetMethodIL(method); if (methodIL == null) { return; } // TODO: Remove this code once CppCodegen is able to generate code for the reflection startup path. // The startup path runs before any user code is executed. // For now we replace the startup path with a simple "ret". Reflection won't work, but // programs not using reflection will. if (method.Name == ".cctor") { MetadataType owningType = method.OwningType as MetadataType; if (owningType != null && owningType.Name == "ReflectionExecution" && owningType.Namespace == "Internal.Reflection.Execution") { methodIL = new Internal.IL.Stubs.ILStubMethodIL(method, new byte[] { (byte)ILOpcode.ret }, Array.Empty <LocalVariableDefinition>(), null); } } try { // TODO: hacky special-case if (method.Name == "_ecvt_s") { throw new NotImplementedException(); } var ilImporter = new ILImporter(_compilation, this, method, methodIL); CompilerTypeSystemContext typeSystemContext = _compilation.TypeSystemContext; MethodDebugInformation debugInfo = _compilation.GetDebugInfo(methodIL); if (!_compilation.Options.NoLineNumbers) { IEnumerable <ILSequencePoint> sequencePoints = debugInfo.GetSequencePoints(); if (sequencePoints != null) { ilImporter.SetSequencePoints(sequencePoints); } } IEnumerable <ILLocalVariable> localVariables = debugInfo.GetLocalVariables(); if (localVariables != null) { ilImporter.SetLocalVariables(localVariables); } IEnumerable <string> parameters = GetParameterNamesForMethod(method); if (parameters != null) { ilImporter.SetParameterNames(parameters); } ilImporter.Compile(methodCodeNodeNeedingCode); } catch (Exception e) { _compilation.Log.WriteLine(e.Message + " (" + method + ")"); var builder = new CppGenerationBuffer(); builder.AppendLine(); builder.Append(GetCppMethodDeclaration(method, true)); builder.AppendLine(); builder.Append("{"); builder.Indent(); builder.AppendLine(); builder.Append("throw 0xC000C000;"); builder.Exdent(); builder.AppendLine(); builder.Append("}"); methodCodeNodeNeedingCode.SetCode(builder.ToString(), Array.Empty <Object>()); } }
// https://github.com/dotnet/corefx/blob/9802644d90aa7fe6aba6d621724a307212303d08/src/System.Diagnostics.StackTrace.Symbols/src/System/Diagnostics/StackTrace/Symbols.cs private static void GetSourceLineInfo(MetadataReader reader, int methodToken, int ilOffset, out string sourceFile, out int sourceLine, out int sourceColumn) { sourceFile = null; sourceLine = 0; sourceColumn = 0; if (reader != null) { Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind == HandleKind.MethodDefinition) { MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); MethodDebugInformation methodInfo = reader.GetMethodDebugInformation(methodDebugHandle); if (!methodInfo.SequencePointsBlob.IsNil) { try { SequencePointCollection sequencePoints = methodInfo.GetSequencePoints(); int sequencePointCount = 0; foreach (SequencePoint sequence in sequencePoints) { sequencePointCount++; } if (sequencePointCount > 0) { int[] offsets = new int[sequencePointCount]; int[] lines = new int[sequencePointCount]; int[] columns = new int[sequencePointCount]; DocumentHandle[] documents = new DocumentHandle[sequencePointCount]; int i = 0; foreach (SequencePoint sequence in sequencePoints) { offsets[i] = sequence.Offset; lines[i] = sequence.StartLine; columns[i] = sequence.StartColumn; documents[i] = sequence.Document; i++; } // Search for the correct IL offset int j; for (j = 0; j < sequencePointCount; j++) { // look for the entry matching the one we're looking for if (offsets[j] >= ilOffset) { // if this offset is > what we're looking for, ajdust the index if (offsets[j] > ilOffset && j > 0) { j--; } break; } } // If we didn't find a match, default to the last sequence point if (j == sequencePointCount) { j--; } while (lines[j] == SequencePoint.HiddenLine && j > 0) { j--; } if (lines[j] != SequencePoint.HiddenLine) { sourceLine = lines[j]; sourceColumn = columns[j]; } var doc = reader.GetDocument(documents[j]); sourceFile = reader.GetString(doc.Name); } } catch { } } } } }
public ILStubMethodIL(MethodDesc owningMethod, byte[] ilBytes, LocalVariableDefinition[] locals, Object[] tokens, ILExceptionRegion[] exceptionRegions = null, MethodDebugInformation debugInfo = null) { _ilBytes = ilBytes; _locals = locals; _tokens = tokens; _method = owningMethod; _maxStack = MaxStackNotSet; if (exceptionRegions == null) { exceptionRegions = Array.Empty <ILExceptionRegion>(); } _exceptionRegions = exceptionRegions; if (debugInfo == null) { debugInfo = MethodDebugInformation.None; } _debugInformation = debugInfo; }
internal static bool GetSequencePoints(IntPtr symbolReaderHandle, int methodToken, out IntPtr points, out int pointsCount) { Debug.Assert(symbolReaderHandle != IntPtr.Zero); pointsCount = 0; points = IntPtr.Zero; Debug.Assert(symbolReaderHandle != IntPtr.Zero); GCHandle gch = GCHandle.FromIntPtr(symbolReaderHandle); MetadataReader reader = ((OpenedReader)gch.Target).Reader; try { Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind != HandleKind.MethodDefinition) { return(false); } MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); if (methodDebugHandle.IsNil) { return(false); } MethodDebugInformation methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); var list = new List <DbgSequencePoint>(); foreach (SequencePoint p in sequencePoints) { list.Add(new DbgSequencePoint() { startLine = p.StartLine, endLine = p.EndLine, startColumn = p.StartColumn, endColumn = p.EndColumn, offset = p.Offset }); } if (list.Count == 0) { return(true); } var structSize = Marshal.SizeOf <DbgSequencePoint>(); IntPtr allPoints = Marshal.AllocCoTaskMem(list.Count * structSize); var currentPtr = allPoints; foreach (var p in list) { Marshal.StructureToPtr(p, currentPtr, false); currentPtr = (IntPtr)(currentPtr.ToInt64() + structSize); } points = allPoints; pointsCount = list.Count; return(true); } catch { } return(false); }
internal static bool GetStepRangesFromIP(IntPtr symbolReaderHandle, int ip, int methodToken, out uint ilStartOffset, out uint ilEndOffset) { Debug.Assert(symbolReaderHandle != IntPtr.Zero); ilStartOffset = 0; ilEndOffset = 0; Debug.Assert(symbolReaderHandle != IntPtr.Zero); GCHandle gch = GCHandle.FromIntPtr(symbolReaderHandle); MetadataReader reader = ((OpenedReader)gch.Target).Reader; try { Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind != HandleKind.MethodDefinition) { return(false); } MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); if (methodDebugHandle.IsNil) { return(false); } MethodDebugInformation methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); var list = new List <SequencePoint>(); foreach (SequencePoint p in sequencePoints) { list.Add(p); } var pointsArray = list.ToArray(); for (int i = 1; i < pointsArray.Length; i++) { SequencePoint p = pointsArray[i]; if (p.Offset > ip && p.StartLine != 0 && p.StartLine != SequencePoint.HiddenLine) { ilStartOffset = (uint)pointsArray[0].Offset; for (int j = i - 1; j > 0; j--) { if (pointsArray[j].Offset <= ip) { ilStartOffset = (uint)pointsArray[j].Offset; break; } } ilEndOffset = (uint)p.Offset; return(true); } } // let's handle correctly last step range from last sequence point till // end of the method. if (pointsArray.Length > 0) { ilStartOffset = (uint)pointsArray[0].Offset; for (int j = pointsArray.Length - 1; j > 0; j--) { if (pointsArray[j].Offset <= ip) { ilStartOffset = (uint)pointsArray[j].Offset; break; } } ilEndOffset = ilStartOffset; // Should set this to IL code size in calling code return(true); } } catch { } return(false); }
/// <summary> /// Returns source line number and source file name for given IL offset and method token. /// </summary> /// <param name="symbolReaderHandle">symbol reader handle returned by LoadSymbolsForModule</param> /// <param name="methodToken">method token</param> /// <param name="ilOffset">IL offset</param> /// <param name="sequencePoint">sequence point return</param> /// <returns> true if information is available</returns> private static bool GetSequencePointByILOffset(IntPtr symbolReaderHandle, int methodToken, long ilOffset, out DbgSequencePoint sequencePoint) { Debug.Assert(symbolReaderHandle != IntPtr.Zero); sequencePoint.document = IntPtr.Zero; sequencePoint.startLine = 0; sequencePoint.startColumn = 0; sequencePoint.endLine = 0; sequencePoint.endColumn = 0; sequencePoint.offset = 0; try { GCHandle gch = GCHandle.FromIntPtr(symbolReaderHandle); MetadataReader reader = ((OpenedReader)gch.Target).Reader; Handle handle = MetadataTokens.Handle(methodToken); if (handle.Kind != HandleKind.MethodDefinition) { return(false); } MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle(); if (methodDebugHandle.IsNil) { return(false); } MethodDebugInformation methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle); SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints(); SequencePoint nearestPoint = sequencePoints.GetEnumerator().Current; bool found = false; foreach (SequencePoint point in sequencePoints) { if (found && point.Offset > ilOffset) { break; } if (!point.IsHidden) { nearestPoint = point; found = true; } } if (!found || nearestPoint.StartLine == 0) { return(false); } var fileName = reader.GetString(reader.GetDocument(nearestPoint.Document).Name); sequencePoint.document = Marshal.StringToBSTR(fileName); sequencePoint.startLine = nearestPoint.StartLine; sequencePoint.startColumn = nearestPoint.StartColumn; sequencePoint.endLine = nearestPoint.EndLine; sequencePoint.endColumn = nearestPoint.EndColumn; sequencePoint.offset = nearestPoint.Offset; fileName = null; return(true); } catch { } return(false); }
public ILStubMethodIL(MethodDesc owningMethod, byte[] ilBytes, LocalVariableDefinition[] locals, Object[] tokens, MethodDebugInformation debugInfo = null) { _ilBytes = ilBytes; _locals = locals; _tokens = tokens; _method = owningMethod; _maxStack = MaxStackNotSet; if (debugInfo == null) { debugInfo = MethodDebugInformation.None; } _debugInformation = debugInfo; }
public void InitializeDebugInfo(MethodDebugInformation debugInfo) { Debug.Assert(_debugInfo == null); _debugInfo = debugInfo; }
public static List <SequencePoint> GetSequencePointsFromMethodDebugInformation(MethodDebugInformation method) { return(method.GetSequencePoints().ToList()); }
public void Write(MethodDebugInformation info) { symbol_writer.Write(info); }
static Collection <ScopeDebugInformation> ReadScopeAndLocals(PdbScope [] scopes, MethodDebugInformation info) { var symbols = new Collection <ScopeDebugInformation> (scopes.Length); foreach (PdbScope scope in scopes) { if (scope != null) { symbols.Add(ReadScopeAndLocals(scope, info)); } } return(symbols); }
public void CompileMethod(CppMethodCodeNode methodCodeNodeNeedingCode) { MethodDesc method = methodCodeNodeNeedingCode.Method; _compilation.Log.WriteLine("Compiling " + method.ToString()); if (method.HasCustomAttribute("System.Runtime", "RuntimeImportAttribute")) { CompileExternMethod(methodCodeNodeNeedingCode, ((EcmaMethod)method).GetRuntimeImportName()); return; } if (method.IsRawPInvoke()) { CompileExternMethod(methodCodeNodeNeedingCode, method.GetPInvokeMethodMetadata().Name ?? method.Name); return; } var methodIL = _compilation.GetMethodIL(method); if (methodIL == null) { return; } try { var ilImporter = new ILImporter(_compilation, this, method, methodIL); CompilerTypeSystemContext typeSystemContext = _compilation.TypeSystemContext; MethodDebugInformation debugInfo = _compilation.GetDebugInfo(methodIL); if (!_compilation.Options.NoLineNumbers) { IEnumerable <ILSequencePoint> sequencePoints = debugInfo.GetSequencePoints(); if (sequencePoints != null) { ilImporter.SetSequencePoints(sequencePoints); } } IEnumerable <ILLocalVariable> localVariables = debugInfo.GetLocalVariables(); if (localVariables != null) { ilImporter.SetLocalVariables(localVariables); } IEnumerable <string> parameters = GetParameterNamesForMethod(method); if (parameters != null) { ilImporter.SetParameterNames(parameters); } ilImporter.Compile(methodCodeNodeNeedingCode); } catch (Exception e) { _compilation.Log.WriteLine(e.Message + " (" + method + ")"); var builder = new CppGenerationBuffer(); builder.AppendLine(); builder.Append(GetCppMethodDeclaration(method, true)); builder.AppendLine(); builder.Append("{"); builder.Indent(); builder.AppendLine(); builder.Append("throw 0xC000C000;"); builder.Exdent(); builder.AppendLine(); builder.Append("}"); methodCodeNodeNeedingCode.SetCode(builder.ToString(), Array.Empty <Object>()); } }
public MethodIL Link(MethodDesc owningMethod) { int totalLength = 0; int numSequencePoints = 0; for (int i = 0; i < _codeStreams.Count; i++) { ILCodeStream ilCodeStream = _codeStreams[i]; ilCodeStream._startOffsetForLinking = totalLength; totalLength += ilCodeStream._length; numSequencePoints += ilCodeStream._sequencePoints.Count; } byte[] ilInstructions = new byte[totalLength]; int copiedLength = 0; for (int i = 0; i < _codeStreams.Count; i++) { ILCodeStream ilCodeStream = _codeStreams[i]; ilCodeStream.PatchLabels(); Array.Copy(ilCodeStream._instructions, 0, ilInstructions, copiedLength, ilCodeStream._length); copiedLength += ilCodeStream._length; } MethodDebugInformation debugInfo = null; if (numSequencePoints > 0) { ILSequencePoint[] sequencePoints = new ILSequencePoint[numSequencePoints]; int copiedSequencePointLength = 0; for (int codeStreamIndex = 0; codeStreamIndex < _codeStreams.Count; codeStreamIndex++) { ILCodeStream ilCodeStream = _codeStreams[codeStreamIndex]; for (int sequencePointIndex = 0; sequencePointIndex < ilCodeStream._sequencePoints.Count; sequencePointIndex++) { ILSequencePoint sequencePoint = ilCodeStream._sequencePoints[sequencePointIndex]; sequencePoints[copiedSequencePointLength] = new ILSequencePoint( ilCodeStream._startOffsetForLinking + sequencePoint.Offset, sequencePoint.Document, sequencePoint.LineNumber); copiedSequencePointLength++; } } debugInfo = new EmittedMethodDebugInformation(sequencePoints); } ILExceptionRegion[] exceptionRegions = null; int numberOfExceptionRegions = _finallyRegions.Count; if (numberOfExceptionRegions > 0) { exceptionRegions = new ILExceptionRegion[numberOfExceptionRegions]; for (int i = 0; i < _finallyRegions.Count; i++) { ILExceptionRegionBuilder region = _finallyRegions[i]; Debug.Assert(region.IsDefined); exceptionRegions[i] = new ILExceptionRegion(ILExceptionRegionKind.Finally, region.TryOffset, region.TryLength, region.HandlerOffset, region.HandlerLength, classToken: 0, filterOffset: 0); } } var result = new ILStubMethodIL(owningMethod, ilInstructions, _locals.ToArray(), _tokens.ToArray(), exceptionRegions, debugInfo); result.CheckStackBalance(); return(result); }
const int lineNumberIndicatingHiddenLine = 16707566; //0xfeefee #if NETCOREAPP1_0 static SequencePoint FirstOrDefaultUnhiddenSequencePoint(MethodDebugInformation body) => body.SequencePoints.FirstOrDefault(sp => sp != null && sp.StartLine != lineNumberIndicatingHiddenLine);
public void WriteIteratorScopes(StateMachineScopeDebugInformation state_machine, MethodDebugInformation debug_info) { Write(CustomMetadataType.IteratorScopes, () => { var scopes = state_machine.Scopes; writer.WriteInt32(scopes.Count); foreach (var scope in scopes) { var start = scope.Start.Offset; var end = scope.End.IsEndOfMethod ? debug_info.code_size : scope.End.Offset; writer.WriteInt32(start); writer.WriteInt32(end - 1); } }); }
public void WriteSequencePoints(MethodDebugInformation info) { int num = -1; int num2 = -1; base.WriteCompressedUInt32(info.local_var_token.RID); if (!info.TryGetUniqueDocument(out Document document)) { document = null; } for (int i = 0; i < info.SequencePoints.Count; i++) { SequencePoint sequencePoint = info.SequencePoints[i]; Document document2 = sequencePoint.Document; if (document != document2) { MetadataToken documentToken = metadata.GetDocumentToken(document2); if (document != null) { base.WriteCompressedUInt32(0u); } base.WriteCompressedUInt32(documentToken.RID); document = document2; } if (i > 0) { base.WriteCompressedUInt32((uint)(sequencePoint.Offset - info.SequencePoints[i - 1].Offset)); } else { base.WriteCompressedUInt32((uint)sequencePoint.Offset); } if (sequencePoint.IsHidden) { base.WriteInt16(0); } else { int num3 = sequencePoint.EndLine - sequencePoint.StartLine; int value = sequencePoint.EndColumn - sequencePoint.StartColumn; base.WriteCompressedUInt32((uint)num3); if (num3 == 0) { base.WriteCompressedUInt32((uint)value); } else { base.WriteCompressedInt32(value); } if (num < 0) { base.WriteCompressedUInt32((uint)sequencePoint.StartLine); base.WriteCompressedUInt32((uint)sequencePoint.StartColumn); } else { base.WriteCompressedInt32(sequencePoint.StartLine - num); base.WriteCompressedInt32(sequencePoint.StartColumn - num2); } num = sequencePoint.StartLine; num2 = sequencePoint.StartColumn; } } }