示例#1
0
        private void InstrumentModule()
        {
            using (var stream = new FileStream(_module, FileMode.Open, FileAccess.ReadWrite))
                using (var resolver = new DefaultAssemblyResolver())
                {
                    resolver.AddSearchDirectory(Path.GetDirectoryName(_module));
                    var parameters = new ReaderParameters {
                        ReadSymbols = true, AssemblyResolver = resolver
                    };

                    using (var module = ModuleDefinition.ReadModule(stream, parameters))
                    {
                        var types = module.GetTypes();
                        foreach (TypeDefinition type in types)
                        {
                            var actualType = type.DeclaringType ?? type;
                            if (!actualType.CustomAttributes.Any(IsExcludeAttribute) &&
                                !InstrumentationHelper.IsTypeExcluded(_module, actualType.FullName, _excludeFilters) &&
                                InstrumentationHelper.IsTypeIncluded(_module, actualType.FullName, _includeFilters))
                            {
                                InstrumentType(type);
                            }
                        }

                        module.Write(stream);
                    }
                }
        }
        public void TestIsTypeExcludedAndIncludedWithFilter(string filter)
        {
            var result = InstrumentationHelper.IsTypeExcluded("Module.dll", "a.b.Dto", new[] { filter });

            Assert.True(result);

            result = InstrumentationHelper.IsTypeIncluded("Module.dll", "a.b.Dto", new[] { filter });
            Assert.True(result);
        }
        public void TestIsTypeExcludedAndIncludedWithMatchingAndMismatchingFilter(string filter)
        {
            var filters = new[] { "[Mismatch]*", filter, "[Mismatch]*" };

            var result = InstrumentationHelper.IsTypeExcluded("Module.dll", "a.b.Dto", filters);

            Assert.True(result);

            result = InstrumentationHelper.IsTypeIncluded("Module.dll", "a.b.Dto", filters);
            Assert.True(result);
        }
示例#4
0
        private void InstrumentModule()
        {
            using (var stream = new FileStream(_module, FileMode.Open, FileAccess.ReadWrite))
                using (var resolver = new DefaultAssemblyResolver())
                {
                    resolver.AddSearchDirectory(Path.GetDirectoryName(_module));
                    var parameters = new ReaderParameters {
                        ReadSymbols = true, AssemblyResolver = resolver
                    };
                    if (Path.GetFileNameWithoutExtension(_module) == "System.Private.CoreLib")
                    {
                        parameters.MetadataImporterProvider = new CoreLibMetadataImporterProvider();
                    }

                    using (var module = ModuleDefinition.ReadModule(stream, parameters))
                    {
                        var types = module.GetTypes();
                        AddCustomModuleTrackerToModule(module);

                        var sourceLinkDebugInfo = module.CustomDebugInformations.FirstOrDefault(c => c.Kind == CustomDebugInformationKind.SourceLink);
                        if (sourceLinkDebugInfo != null)
                        {
                            _result.SourceLink = ((SourceLinkDebugInformation)sourceLinkDebugInfo).Content;
                        }

                        foreach (TypeDefinition type in types)
                        {
                            var actualType = type.DeclaringType ?? type;
                            if (!actualType.CustomAttributes.Any(IsExcludeAttribute) &&
                                !InstrumentationHelper.IsTypeExcluded(_module, actualType.FullName, _excludeFilters) &&
                                InstrumentationHelper.IsTypeIncluded(_module, actualType.FullName, _includeFilters))
                            {
                                InstrumentType(type);
                            }
                        }

                        // Fixup the custom tracker class constructor, according to all instrumented types
                        Instruction lastInstr = _customTrackerClassConstructorIl.Body.Instructions.Last();
                        _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Ldc_I4, _result.HitCandidates.Count));
                        _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Newarr, module.TypeSystem.Int32));
                        _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Stsfld, _customTrackerHitsArray));
                        _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Ldstr, _result.HitsFilePath));
                        _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Stsfld, _customTrackerHitsFilePath));

                        module.Write(stream);
                    }
                }
        }
示例#5
0
        private void InstrumentModule()
        {
            using (var stream = new FileStream(_module, FileMode.Open, FileAccess.ReadWrite))
                using (var resolver = new DefaultAssemblyResolver())
                {
                    resolver.AddSearchDirectory(Path.GetDirectoryName(_module));
                    var parameters = new ReaderParameters {
                        ReadSymbols = true, AssemblyResolver = resolver
                    };

                    using (var module = ModuleDefinition.ReadModule(stream, parameters))
                    {
                        var types = module.GetTypes();
                        AddCustomModuleTrackerToModule(module);

                        foreach (TypeDefinition type in types)
                        {
                            var actualType = type.DeclaringType ?? type;
                            if (!actualType.CustomAttributes.Any(IsExcludeAttribute) &&
                                !InstrumentationHelper.IsTypeExcluded(_module, actualType.FullName, _excludeFilters) &&
                                InstrumentationHelper.IsTypeIncluded(_module, actualType.FullName, _includeFilters))
                            {
                                InstrumentType(type);
                            }
                        }

                        // Fixup the custom tracker class constructor, according to all instrumented types
                        Instruction lastInstr = _customTrackerClassConstructorIl.Body.Instructions.Last();
                        _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Ldc_I4, _result.HitCandidates.Count));
                        _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Newarr, module.TypeSystem.Int32));
                        _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Stsfld, _customTrackerHitsArray));
                        _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Ldstr, _result.HitsFilePath));
                        _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Stsfld, _customTrackerHitsFilePath));

                        module.Write(stream);
                    }
                }
        }
        public void TestIsTypeIncludedWithoutFilter()
        {
            var result = InstrumentationHelper.IsTypeIncluded("Module.dll", "a.b.Dto", new string[0]);

            Assert.True(result);
        }
示例#7
0
        private void InstrumentModule()
        {
            using (var stream = new FileStream(_module, FileMode.Open, FileAccess.ReadWrite))
                using (var resolver = new DefaultAssemblyResolver())
                {
                    resolver.AddSearchDirectory(Path.GetDirectoryName(_module));
                    var parameters = new ReaderParameters {
                        ReadSymbols = true, AssemblyResolver = resolver
                    };
                    if (_isCoreLibrary)
                    {
                        parameters.MetadataImporterProvider = new CoreLibMetadataImporterProvider();
                    }

                    using (var module = ModuleDefinition.ReadModule(stream, parameters))
                    {
                        var containsAppContext = module.GetType(nameof(System), nameof(AppContext)) != null;
                        var types = module.GetTypes();
                        AddCustomModuleTrackerToModule(module);

                        var sourceLinkDebugInfo = module.CustomDebugInformations.FirstOrDefault(c => c.Kind == CustomDebugInformationKind.SourceLink);
                        if (sourceLinkDebugInfo != null)
                        {
                            _result.SourceLink = ((SourceLinkDebugInformation)sourceLinkDebugInfo).Content;
                        }

                        foreach (TypeDefinition type in types)
                        {
                            var actualType = type.DeclaringType ?? type;
                            if (!actualType.CustomAttributes.Any(IsExcludeAttribute)
                                // Instrumenting Interlocked which is used for recording hits would cause an infinite loop.
                                && (!_isCoreLibrary || actualType.FullName != "System.Threading.Interlocked") &&
                                !InstrumentationHelper.IsTypeExcluded(_module, actualType.FullName, _excludeFilters) &&
                                InstrumentationHelper.IsTypeIncluded(_module, actualType.FullName, _includeFilters))
                            {
                                InstrumentType(type);
                            }
                        }

                        // Fixup the custom tracker class constructor, according to all instrumented types
                        if (_customTrackerRegisterUnloadEventsMethod == null)
                        {
                            _customTrackerRegisterUnloadEventsMethod = new MethodReference(
                                nameof(ModuleTrackerTemplate.RegisterUnloadEvents), module.TypeSystem.Void, _customTrackerTypeDef);
                        }

                        Instruction lastInstr = _customTrackerClassConstructorIl.Body.Instructions.Last();

                        if (!containsAppContext)
                        {
                            // For "normal" cases, where the instrumented assembly is not the core library, we add a call to
                            // RegisterUnloadEvents to the static constructor of the generated custom tracker. Due to static
                            // initialization constraints, the core library is handled separately below.
                            _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Call, _customTrackerRegisterUnloadEventsMethod));
                        }

                        _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Ldc_I4, _result.HitCandidates.Count));
                        _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Newarr, module.TypeSystem.Int32));
                        _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Stsfld, _customTrackerHitsArray));
                        _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Ldstr, _result.HitsFilePath));
                        _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Stsfld, _customTrackerHitsFilePath));
                        _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(_singleHit ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0));
                        _customTrackerClassConstructorIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Stsfld, _customTrackerSingleHit));

                        if (containsAppContext)
                        {
                            // Handle the core library by instrumenting System.AppContext.OnProcessExit to directly call
                            // the UnloadModule method of the custom tracker type. This avoids loops between the static
                            // initialization of the custom tracker and the static initialization of the hosting AppDomain
                            // (which for the core library case will be instrumented code).
                            var eventArgsType             = new TypeReference(nameof(System), nameof(EventArgs), module, module.TypeSystem.CoreLibrary);
                            var customTrackerUnloadModule = new MethodReference(nameof(ModuleTrackerTemplate.UnloadModule), module.TypeSystem.Void, _customTrackerTypeDef);
                            customTrackerUnloadModule.Parameters.Add(new ParameterDefinition(module.TypeSystem.Object));
                            customTrackerUnloadModule.Parameters.Add(new ParameterDefinition(eventArgsType));

                            var appContextType      = new TypeReference(nameof(System), nameof(AppContext), module, module.TypeSystem.CoreLibrary);
                            var onProcessExitMethod = new MethodReference("OnProcessExit", module.TypeSystem.Void, appContextType).Resolve();
                            var onProcessExitIl     = onProcessExitMethod.Body.GetILProcessor();

                            lastInstr = onProcessExitIl.Body.Instructions.Last();
                            onProcessExitIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Ldnull));
                            onProcessExitIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Ldnull));
                            onProcessExitIl.InsertBefore(lastInstr, Instruction.Create(OpCodes.Call, customTrackerUnloadModule));
                        }

                        module.Write(stream, new WriterParameters {
                            WriteSymbols = true
                        });
                    }
                }
        }