void WriteAsyncMethodSteppingInformation(PdbAsyncMethodCustomDebugInfo cdi) { if (!methodContext.HasBody) { helper.Error("Method has no body, can't write custom debug info: " + cdi.Kind); return; } uint catchHandlerOffset; if (cdi.CatchHandlerInstruction == null) { catchHandlerOffset = 0; } else { catchHandlerOffset = methodContext.GetOffset(cdi.CatchHandlerInstruction) + 1; } writer.WriteUInt32(catchHandlerOffset); var cdiStepInfos = cdi.StepInfos; int count = cdiStepInfos.Count; for (int i = 0; i < count; i++) { var info = cdiStepInfos[i]; if (info.YieldInstruction == null) { helper.Error("YieldInstruction is null"); return; } if (info.BreakpointMethod == null) { helper.Error("BreakpointMethod is null"); return; } if (info.BreakpointInstruction == null) { helper.Error("BreakpointInstruction is null"); return; } uint yieldOffset = methodContext.GetOffset(info.YieldInstruction); uint resumeOffset; if (methodContext.IsSameMethod(info.BreakpointMethod)) { resumeOffset = methodContext.GetOffset(info.BreakpointInstruction); } else { resumeOffset = GetOffsetSlow(info.BreakpointMethod, info.BreakpointInstruction); } uint resumeMethodRid = systemMetadata.GetRid(info.BreakpointMethod); writer.WriteUInt32(yieldOffset); writer.WriteUInt32(resumeOffset); writer.WriteCompressedUInt32(resumeMethodRid); } }
protected override PdbCustomDebugInfo CloneOther(PdbCustomDebugInfo source) { switch (source) { case PdbAsyncMethodCustomDebugInfo i: var n = new PdbAsyncMethodCustomDebugInfo(i.StepInfos.Count) { CatchHandlerInstruction = GetInstruction(i.CatchHandlerInstruction), KickoffMethod = Importer.Import(i.KickoffMethod).ResolveMethodDefThrow() }; for (var j = 0; j < i.StepInfos.Count; j++) { n.StepInfos.Add(new PdbAsyncStepInfo( GetInstruction(i.StepInfos[j].YieldInstruction), Importer.Import(i.StepInfos[j].BreakpointMethod).ResolveMethodDefThrow(), GetInstruction(i.StepInfos[j].BreakpointInstruction) )); } return(n); case PdbStateMachineHoistedLocalScopesCustomDebugInfo i: var nls = new PdbStateMachineHoistedLocalScopesCustomDebugInfo(i.Scopes.Count); foreach (var si in nls.Scopes) { nls.Scopes.Add(new StateMachineHoistedLocalScope( GetInstruction(si.Start), GetInstruction(si.End))); } return(nls); case PdbIteratorMethodCustomDebugInfo i: var im = new PdbIteratorMethodCustomDebugInfo { KickoffMethod = Importer.Import(i.KickoffMethod).ResolveMethodDefThrow() }; return(im); case PdbDynamicLocalsCustomDebugInfo i: var ndl = new PdbDynamicLocalsCustomDebugInfo(i.Locals.Count); foreach (var si in ndl.Locals) { ndl.Locals.Add(Clone(si)); } return(ndl); case PdbEditAndContinueLocalSlotMapCustomDebugInfo i2: case PdbEditAndContinueLambdaMapCustomDebugInfo i3: return(source); } return(null); }
void WriteAsyncMethod(ref CurrentMethod info, PdbAsyncMethodCustomDebugInfo asyncMethod) { if (asyncMethod.KickoffMethod == null) { Error("KickoffMethod is null"); return; } uint kickoffMethod = GetMethodToken(asyncMethod.KickoffMethod); writer3.DefineKickoffMethod(kickoffMethod); if (asyncMethod.CatchHandlerInstruction != null) { int catchHandlerILOffset = info.GetOffset(asyncMethod.CatchHandlerInstruction); writer3.DefineCatchHandlerILOffset((uint)catchHandlerILOffset); } var stepInfos = asyncMethod.StepInfos; var yieldOffsets = new uint[stepInfos.Count]; var breakpointOffset = new uint[stepInfos.Count]; var breakpointMethods = new uint[stepInfos.Count]; for (int i = 0; i < yieldOffsets.Length; i++) { var stepInfo = stepInfos[i]; if (stepInfo.YieldInstruction == null) { Error("YieldInstruction is null"); return; } if (stepInfo.BreakpointMethod == null) { Error("BreakpointInstruction is null"); return; } if (stepInfo.BreakpointInstruction == null) { Error("BreakpointInstruction is null"); return; } yieldOffsets[i] = (uint)info.GetOffset(stepInfo.YieldInstruction); breakpointOffset[i] = (uint)GetExternalInstructionOffset(ref info, stepInfo.BreakpointMethod, stepInfo.BreakpointInstruction); breakpointMethods[i] = GetMethodToken(stepInfo.BreakpointMethod); } writer3.DefineAsyncStepInfo(yieldOffsets, breakpointOffset, breakpointMethods); }
PdbAsyncMethodCustomDebugInfo TryCreateAsyncMethod(ModuleDef module, int asyncKickoffMethod, IList <PdbAsyncStepInfo> asyncStepInfos, Instruction asyncCatchHandler) { var kickoffToken = new MDToken(asyncKickoffMethod); if (kickoffToken.Table != Table.Method) { return(null); } var asyncMethod = new PdbAsyncMethodCustomDebugInfo(asyncStepInfos.Count); asyncMethod.KickoffMethod = module.ResolveToken(kickoffToken) as MethodDef; asyncMethod.CatchHandlerInstruction = asyncCatchHandler; foreach (var info in asyncStepInfos) { asyncMethod.StepInfos.Add(info); } return(asyncMethod); }
public static PdbAsyncMethodCustomDebugInfo TryCreateAsyncMethod(ModuleDef module, MethodDef method, CilBody body, int asyncKickoffMethod, IList <SymbolAsyncStepInfo> asyncStepInfos, uint?asyncCatchHandlerILOffset) { var kickoffToken = new MDToken(asyncKickoffMethod); if (kickoffToken.Table != Table.Method) { return(null); } var kickoffMethod = module.ResolveToken(kickoffToken) as MethodDef; var asyncMethod = new PdbAsyncMethodCustomDebugInfo(asyncStepInfos.Count); asyncMethod.KickoffMethod = kickoffMethod; if (asyncCatchHandlerILOffset is not null) { asyncMethod.CatchHandlerInstruction = GetInstruction(body, asyncCatchHandlerILOffset.Value); Debug.Assert(asyncMethod.CatchHandlerInstruction is not null); } int count = asyncStepInfos.Count; for (int i = 0; i < count; i++) { var rawInfo = asyncStepInfos[i]; var yieldInstruction = GetInstruction(body, rawInfo.YieldOffset); Debug.Assert(yieldInstruction is not null); if (yieldInstruction is null) { continue; } MethodDef breakpointMethod; Instruction breakpointInstruction; if (method.MDToken.Raw == rawInfo.BreakpointMethod) { breakpointMethod = method; breakpointInstruction = GetInstruction(body, rawInfo.BreakpointOffset); } else { var breakpointMethodToken = new MDToken(rawInfo.BreakpointMethod); Debug.Assert(breakpointMethodToken.Table == Table.Method); if (breakpointMethodToken.Table != Table.Method) { continue; } breakpointMethod = module.ResolveToken(breakpointMethodToken) as MethodDef; Debug.Assert(breakpointMethod is not null); if (breakpointMethod is null) { continue; } breakpointInstruction = GetInstruction(breakpointMethod.Body, rawInfo.BreakpointOffset); } Debug.Assert(breakpointInstruction is not null); if (breakpointInstruction is null) { continue; } asyncMethod.StepInfos.Add(new PdbAsyncStepInfo(yieldInstruction, breakpointMethod, breakpointInstruction)); } return(asyncMethod); }
void GetPseudoCustomDebugInfos(IList <PdbCustomDebugInfo> customDebugInfos, List <PdbCustomDebugInfo> cdiBuilder, out PdbAsyncMethodCustomDebugInfo asyncMethod) { cdiBuilder.Clear(); asyncMethod = null; foreach (var cdi in customDebugInfos) { switch (cdi.Kind) { case PdbCustomDebugInfoKind.AsyncMethod: if (asyncMethod != null) { Error("Duplicate async method custom debug info"); } else { asyncMethod = (PdbAsyncMethodCustomDebugInfo)cdi; } break; default: if ((uint)cdi.Kind > byte.MaxValue) { Error("Custom debug info {0} isn't supported by Windows PDB files", cdi.Kind); } else { cdiBuilder.Add(cdi); } break; } } }
void GetPseudoCustomDebugInfos(IList <PdbCustomDebugInfo> customDebugInfos, List <PdbCustomDebugInfo> cdiBuilder, out PdbAsyncMethodCustomDebugInfo asyncMethod) { cdiBuilder.Clear(); asyncMethod = null; int count = customDebugInfos.Count; for (int i = 0; i < count; i++) { var cdi = customDebugInfos[i]; switch (cdi.Kind) { case PdbCustomDebugInfoKind.AsyncMethod: if (!(asyncMethod is null)) { Error("Duplicate async method custom debug info"); } else { asyncMethod = (PdbAsyncMethodCustomDebugInfo)cdi; } break;