System.InvalidProgramException在Microsoft安全更新MS13-004之后在MSTest中执行单元测试时

Ale*_*lex 6 c# mstest castle-windsor castle-dynamicproxy nuget-package

在2013年1月8日应用Microsoft安全更新http://technet.microsoft.com/en-us/security/bulletin/ms13-004后,我们已经开始在我们的构建服务器和本地的CI构建中遇到故障在我们的开发盒上运行测试.

我们得到一个System.InvalidProgramException:公共语言运行时检测到一个无效的程序.

这仅在使用使用Castle Windsor DynamicProxy的MSTest运行测试时才会发生,尽管我不相信DynamicProxy在这里有问题.

下面将生成一个生成异常的示例代码.

    [TestMethod]
    public void ShouldBeAbleToGenerateADynamicProxyForAnObject()
    {
        var container = new WindsorContainer();

        container.Register(Component.For<TestInterceptor>());

        container.Register(Component.For<ISomething>()
                               .Instance(new TestDependency("Called from test framework."))
                               .LifeStyle.Transient);

        container.Register(Component.For<IService>()
                               .ImplementedBy<TestService>()
                               .Interceptors(InterceptorReference.ForType<TestInterceptor>())
                               .Anywhere
                               .LifeStyle.Transient);

        var service = container.Resolve<IService>();
        Assert.AreEqual("Called from test framework.", service.MethodNumberOne());
    }    
Run Code Online (Sandbox Code Playgroud)

这会生成一个堆栈跟踪,最终会在DynamicProxy中调用MixinData构造函数时抛出异常:

Castle.DynamicProxy.MixinData..ctor(IEnumerable`1 mixinInstances)Castle.DynamicProxy.ProxyGenerationOptions.Initialize()Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode(Type proxyTargetType,Type [] interfaces,ProxyGenerationOptions options)Castle.DynamicProxy.DefaultProxyBuilder. CreateInterfaceProxyTypeWithTarget(Type interfaceToProxy,Type [] additionalInterfacesToProxy,Type targetType,ProxyGenerationOptions options)Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyTypeWithTarget(Type interfaceToProxy,Type [] additionalInterfacesToProxy,Type targetType,ProxyGenerationOptions options)Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithTarget(Type interfaceToProxy,Type [] additionalInterfacesToProxy,对象目标,ProxyGenerationOptions选项,IInterceptor []拦截器)Castle.Windsor.Proxy.DefaultProxyFactory.Create(的iKernel内核,对象目标,ComponentModel模型,CreationContext上下文中,对象[],构造函数)Castle.M icroKernel.ComponentActivator.DefaultComponentActivator.CreateInstance(CreationContext context,ConstructorCandidate constructor,Object [] arguments)Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstance(CreationContext context,ConstructorCandidate constructor,Object [] arguments)Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.Instantiate( CreationContext context)Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context)Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context,Burden burden)Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context,Boolean trackedExternally)Castle. MicroKernel.Lifestyle.AbstractLifestyleManager.Resolve(CreationContext上下文,IReleasePolicy releasePolicy)Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext上下文中,布尔requiresDecommission,布尔instanceRequired,B ·杜垩登和负担)Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext背景下,布尔instanceRequired)Castle.MicroKernel.Handlers.AbstractHandler.Resolve(CreationContext上下文)Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler处理程序,服务类型,IDictionary的additionalArguments,IReleasePolicy政策)Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(服务类型,IDictionary的论点,IReleasePolicy政策)Castle.MicroKernel.DefaultKernel.Resolve(服务类型,IDictionary的参数)Castle.Windsor.WindsorContainer.ResolveT ShouldBeAbleToGenerateADynamicProxyForAnObject()在TestCastleWindsorDynamicProxy.cs:第34行

我的第一个想法是DynamicProxy在创建代理时在安全更新后实际上生成了无效的IL,但据我所知,情况并非如此,因为它没有那么远.我反编译城堡和阶梯通过与调试器和我看到抛出异常按堆栈跟踪,当MixinData构造从ProxyGenerationOptions类通过如下的呼叫称为(注:在上面的代码示例this.mixins将null,但这是在被调用的构造函数的代码中预期和正确处理的):

this.mixinData = new Castle.DynamicProxy.MixinData(this.mixins);
Run Code Online (Sandbox Code Playgroud)

在MSTest运行器之外,一切都按预期工作,我们的应用程序继续运行,当使用MSTest在xUnit或甚至TestDriven.NET中运行单元测试时,它们不会生成异常.我们只看到此行为从Visual Studio运行测试或使用TFS和我们的MSBuild脚本进行自动构建.

在我们向微软提出支持票之前,我想我们会问其他人是否经历过类似的事情,或者对可能导致我们问题的事情有任何想法?

编辑:今天早上经过一些新的事情后,我们发现这实际上似乎与我们正在使用的Castle NuGet包有关.当我们使用最新的NuGet包引用Castle时,我们最终得到了针对.NET Client Profile 4编译的Castle.Core程序集的引用.这个引用是上面例外的原因(为什么?我还不完全确定).更改对为.NET 3.5编译的版本的引用可确保测试在所有方案中按预期传递.

编辑:在进行了一些挖掘之后,似乎确实存在一个链接问题(这让我们有理由回到微软并看看他们要说些什么)Common Language Runtime在单元测试中检测到无效的程序错误

Pet*_*ter 2

我刚刚通过卸载 .net 的 microsoft 安全补丁 kb2742595 在我的一台同事计算机上修复了相同的错误。我猜想安全设置中的某些内容已修复,并且 MSTest 运行程序无法处理新设置。我们没有安装 Castle.Core。