System.InvalidProgramException在Microsoft安全更新MS13-004之后在MSTest中执行unit testing时

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

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

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

下面将生成一个生成exception的示例代码。

[TestMethod] public void ShouldBeAbleToGenerateADynamicProxyForAnObject() { var container = new WindsorContainer(); container.Register(Component.For()); container.Register(Component.For() .Instance(new TestDependency("Called from test framework.")) .LifeStyle.Transient); container.Register(Component.For() .ImplementedBy() .Interceptors(InterceptorReference.ForType()) .Anywhere .LifeStyle.Transient); var service = container.Resolve(); Assert.AreEqual("Called from test framework.", service.MethodNumberOne()); } 

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

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,Object target,ProxyGenerationOptions选项,IInterceptor []拦截器)Castle.Windsor.Proxy.DefaultProxyFactory.Create(IKernel kernel,Object target,ComponentModel model,CreationContext context,Object [] constructorArguments)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 context,IReleasePolicy releasePolicy)Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context,Boolean requiresDecommission,Boolean instanceRequired,B urden&burden)Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context,Boolean instanceRequired)Castle.MicroKernel.Handlers.AbstractHandler.Resolve(CreationContext context)Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler,Type service,IDictionary additionalArguments,IReleasePolicy策略)Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(类型服务,IDictionary参数,IReleasePolicy策略)Castle.MicroKernel.DefaultKernel.Resolve(类型服务,IDictionary参数)Castle.Windsor.WindsorContainer.ResolveT ShouldBeAbleToGenerateADynamicProxyForAnObject()in TestCastleWindsorDynamicProxy.cs:第34行

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

 this.mixinData = new Castle.DynamicProxy.MixinData(this.mixins); 

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

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

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

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

我只是通过卸载用于.net的micrsoft安全补丁kb2742595在我的同事计算机上修复了同样的错误。 我想在安全设置中修复了一些问题,并且MSTest运行器无法处理新设置。 我们没有安装Castle.Core。

尝试运行使用TypeMock的测试时,我遇到了类似的错误。 为了解决这个问题,我在Visual Studio中打开了我的解决方案并选择了TestEdit Test Settings 。 在“ 测试设置”对话框中,我选择了“ 主机”并将其切换为在64位计算机上以64位进程运行测试

如果这有帮助,请告诉我。 如果这与您的错误无关,请告诉我,我将删除我的答案。