Ejemplo n.º 1
0
        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));
        }
Ejemplo n.º 2
0
        DbgLanguageDebugInfo GetOrCreateDebugInfo(RuntimeState state, IDbgDotNetCodeLocation location, CancellationToken cancellationToken)
        {
            DbgLanguageDebugInfoKey key;

            if (location.DbgModule is DbgModule dbgModule)
            {
                key = new DbgLanguageDebugInfoKey(dbgModule, location.Token);
            }
            else
            {
                key = new DbgLanguageDebugInfoKey(location.Module, location.Token);
            }

            var debugInfos = state.DebugInfos;

            lock (state.LockObj) {
                for (int i = debugInfos.Count - 1; i >= 0; i--)
                {
                    var info = debugInfos[i];
                    if (info.key.Equals(key))
                    {
                        if (i != debugInfos.Count - 1)
                        {
                            debugInfos.RemoveAt(i);
                            debugInfos.Add(info);
                        }
                        return(info.debugInfo);
                    }
                }
            }

            var debugInfo = CreateDebugInfo(location, cancellationToken);

            if (debugInfo == null)
            {
                return(null);
            }
            lock (state.LockObj) {
                if (debugInfos.Count == RuntimeState.MAX_CACHED_DEBUG_INFOS)
                {
                    debugInfos.RemoveAt(0);
                }
                debugInfos.Add((key, debugInfo));
            }
            return(debugInfo);
        }
Ejemplo n.º 3
0
        DbgLanguageDebugInfo?CreateDebugInfo(DbgEvaluationContext context, IDbgDotNetCodeLocation location, CancellationToken cancellationToken)
        {
            var result = dbgMethodDebugInfoProvider.GetMethodDebugInfo(context.Runtime, decompiler, location, cancellationToken);

            if (result.DebugInfo is null)
            {
                return(null);
            }

            var runtime = context.Runtime.GetDotNetRuntime();

            if (location.DbgModule is null || !runtime.TryGetMethodToken(location.DbgModule, (int)location.Token, out int methodToken, out int localVarSigTok))
            {
                methodToken    = (int)location.Token;
                localVarSigTok = (int)((result.StateMachineDebugInfo ?? result.DebugInfo)?.Method.Body?.LocalVarSigTok ?? 0);
            }

            return(new DbgLanguageDebugInfo(result.DebugInfo, methodToken, localVarSigTok, result.MethodVersion, location.Offset));
        }
Ejemplo n.º 4
0
        DbgLanguageDebugInfo CreateDebugInfo(DbgEvaluationContext context, IDbgDotNetCodeLocation location, CancellationToken cancellationToken)
        {
            var result = dbgMethodDebugInfoProvider.GetMethodDebugInfo(context.Runtime, decompiler, location, cancellationToken);

            if (result.DebugInfoOrNull == null)
            {
                return(null);
            }

            var runtime = context.Runtime.GetDotNetRuntime();

            if (location.DbgModule == null || !runtime.TryGetMethodToken(location.DbgModule, (int)location.Token, out int methodToken, out int localVarSigTok))
            {
                methodToken    = (int)location.Token;
                localVarSigTok = (int)result.LocalVarSigTok;
            }

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

            return(new DbgLanguageDebugInfo(result.DebugInfoOrNull, methodToken, localVarSigTok, methodVersion, location.Offset));
        }
Ejemplo n.º 5
0
        //TODO: If decompiler settings change, we need to invalidate the cached data in DbgEvaluationContext, see decompiler.Settings.VersionChanged
        DbgLanguageDebugInfo GetOrCreateDebugInfo(DbgEvaluationContext context, RuntimeState state, IDbgDotNetCodeLocation location, CancellationToken cancellationToken)
        {
            DbgLanguageDebugInfoKey key;

            if (location.DbgModule is DbgModule dbgModule)
            {
                key = new DbgLanguageDebugInfoKey(dbgModule, location.Token);
            }
            else
            {
                key = new DbgLanguageDebugInfoKey(location.Module, location.Token);
            }

            var debugInfos = state.DebugInfos;

            lock (state.LockObj) {
                if (debugInfos.Count > 0 && debugInfos[0].debugInfo.MethodDebugInfo.DebugInfoVersion != decompiler.Settings.Version)
                {
                    debugInfos.Clear();
                }
                for (int i = debugInfos.Count - 1; i >= 0; i--)
                {
                    var info = debugInfos[i];
                    if (info.key.Equals(key))
                    {
                        if (i != debugInfos.Count - 1)
                        {
                            debugInfos.RemoveAt(i);
                            debugInfos.Add(info);
                        }
                        return(info.debugInfo);
                    }
                }
            }

            var debugInfo = CreateDebugInfo(context, location, cancellationToken);

            if (debugInfo == null)
            {
                return(null);
            }
            lock (state.LockObj) {
                if (debugInfos.Count == RuntimeState.MAX_CACHED_DEBUG_INFOS)
                {
                    debugInfos.RemoveAt(0);
                }
                debugInfos.Add((key, debugInfo));
            }
            return(debugInfo);
        }
Ejemplo n.º 6
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));
        }
Ejemplo n.º 7
0
 public abstract MethodDebugInfoResult GetMethodDebugInfo(DbgRuntime runtime, IDecompiler decompiler, IDbgDotNetCodeLocation location, CancellationToken cancellationToken);