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);
            }
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        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);
        }
示例#6
0
        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;
                }
            }
        }
示例#7
0
        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;