DbgLanguageDebugInfo CreateDebugInfo(IDbgDotNetCodeLocation location, CancellationToken cancellationToken)
        {
            const DbgLoadModuleOptions options = DbgLoadModuleOptions.AutoLoaded;
            ModuleDef mdModule;

            if (location.DbgModule is DbgModule dbgModule)
            {
                mdModule = dbgMetadataService.TryGetMetadata(dbgModule, options);
            }
            else
            {
                mdModule = dbgMetadataService.TryGetMetadata(location.Module, options);
            }
            Debug.Assert(mdModule != null);
            if (mdModule == null)
            {
                return(null);
            }
            cancellationToken.ThrowIfCancellationRequested();

            var method = mdModule.ResolveToken(location.Token) as MethodDef;

            Debug.Assert(method != null);
            if (method == null)
            {
                return(null);
            }

            var context = new DecompilationContext {
                CancellationToken = cancellationToken,
                CalculateBinSpans = true,
            };
            var output = DecompilerOutputImplCache.Alloc();

            output.Initialize(method.MDToken.Raw);
            //TODO: Whenever the decompiler options change, we need to invalidate our cache and every
            //		single DbgLanguageDebugInfo instance.
            decompiler.Decompile(method, output, context);
            var methodDebugInfo = output.TryGetMethodDebugInfo();

            DecompilerOutputImplCache.Free(ref output);
            cancellationToken.ThrowIfCancellationRequested();
            Debug.Assert(methodDebugInfo != null);
            if (methodDebugInfo == null)
            {
                return(null);
            }

            // We don't support EnC so the version is always 1
            const int methodVersion = 1;

            return(new DbgLanguageDebugInfo(methodDebugInfo, methodVersion, location.Offset));
        }
        DbgCodeRange[] TryGetCodeRanges_UI(DbgModule module, uint token, uint offset)
        {
            uiDispatcher.VerifyAccess();
            var tab                = documentTabService.Value.GetOrCreateActiveTab();
            var documentViewer     = tab.TryGetDocumentViewer();
            var methodDebugService = documentViewer.GetMethodDebugService();
            var moduleId           = dbgModuleIdProviderService.GetModuleId(module);

            if (moduleId == null)
            {
                return(null);
            }

            uint refNavOffset;

            if (offset == EPILOG)
            {
                refNavOffset = DotNetReferenceNavigator.EPILOG;
                var mod = dbgMetadataService.TryGetMetadata(module, DbgLoadModuleOptions.AutoLoaded);
                if (mod?.ResolveToken(token) is MethodDef md && md.Body != null && md.Body.Instructions.Count > 0)
                {
                    offset = md.Body.Instructions[md.Body.Instructions.Count - 1].Offset;
                }
                else
                {
                    return(null);
                }
            }
Exemple #3
0
        DbgLanguageDebugInfo CreateDebugInfo(DbgEvaluationContext context, IDbgDotNetCodeLocation location, CancellationToken cancellationToken)
        {
            const DbgLoadModuleOptions options = DbgLoadModuleOptions.AutoLoaded;
            ModuleDef mdModule;

            if (location.DbgModule is DbgModule dbgModule)
            {
                mdModule = dbgMetadataService.TryGetMetadata(dbgModule, options);
            }
            else
            {
                dbgModule = null;
                mdModule  = dbgMetadataService.TryGetMetadata(location.Module, options);
            }
            Debug.Assert(mdModule != null);
            if (mdModule == null)
            {
                return(null);
            }
            cancellationToken.ThrowIfCancellationRequested();

            var method = mdModule.ResolveToken(location.Token) as MethodDef;

            // Could be null if it's a dynamic assembly. It will get refreshed later and we'll get called again.
            if (method == null)
            {
                return(null);
            }

            var runtime = context.Runtime.GetDotNetRuntime();
            int methodToken, localVarSigTok;

            if (dbgModule == null || !runtime.TryGetMethodToken(dbgModule, method.MDToken.ToInt32(), out methodToken, out localVarSigTok))
            {
                methodToken    = method.MDToken.ToInt32();
                localVarSigTok = (int)(method.Body?.LocalVarSigTok ?? 0);
            }

            var decContext = new DecompilationContext {
                CancellationToken = cancellationToken,
                CalculateBinSpans = true,
            };
            var output = DecompilerOutputImplCache.Alloc();

            output.Initialize(method.MDToken.Raw);
            //TODO: Whenever the decompiler options change, we need to invalidate our cache and every
            //		single DbgLanguageDebugInfo instance.
            decompiler.Decompile(method, output, decContext);
            var methodDebugInfo = output.TryGetMethodDebugInfo();

            DecompilerOutputImplCache.Free(ref output);
            cancellationToken.ThrowIfCancellationRequested();
            Debug.Assert(methodDebugInfo != null);
            if (methodDebugInfo == null)
            {
                return(null);
            }

            // We don't support EnC so the version is always 1
            const int methodVersion = 1;

            return(new DbgLanguageDebugInfo(methodDebugInfo, methodToken, localVarSigTok, methodVersion, location.Offset));
        }