6
votes

After applying the Microsoft Security update on the 8th of January 2013 http://technet.microsoft.com/en-us/security/bulletin/ms13-004 we have started to experience failures in our CI builds on our build servers and locally when running tests on our development boxes.

We get a System.InvalidProgramException: Common Language Runtime detected an invalid program.

This only happens when running tests using MSTest that make use of Castle Windsor DynamicProxy although I am not convinced DynamicProxy is at fault here.

An example piece of code that would generate the exception is below.

    [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());
    }    

This generates a stack trace that ends up with the exception being thrown when invoking the MixinData constructor in DynamicProxy:

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 options, IInterceptor[] interceptors) Castle.Windsor.Proxy.DefaultProxyFactory.Create(IKernel kernel, Object target, ComponentModel model, CreationContext context, Object[] constructorArguments) Castle.MicroKernel.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, Burden& 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 policy) Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy) Castle.MicroKernel.DefaultKernel.Resolve(Type service, IDictionary arguments) Castle.Windsor.WindsorContainer.ResolveT ShouldBeAbleToGenerateADynamicProxyForAnObject() in TestCastleWindsorDynamicProxy.cs: line 34

My first thought was that DynamicProxy was actually generating invalid IL after the security update when creating the Proxy but as far as I can see this is not the case as it is not getting that far. I decompiled Castle and stepped through with the debugger and I see the exception being thrown as per the stack trace, when the MixinData constructor is called from the ProxyGenerationOptions class via a call as below (Note: in the code example above this.mixins will be null but this is expected and handled correctly in the code of the constructor being called):

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

Outside of the MSTest runner everything works as expected, our applications continue to function and when running the unit tests in xUnit or even TestDriven.NET using MSTest they do not generate the exception. We only see this behaviour running tests from Visual Studio or using TFS and our MSBuild scripts for our automated builds.

Before we raise a support ticket with Microsoft I thought we would ask if anyone else has experienced anything similar or has any ideas about what may be causing our issue?

Edit: After going through a few new things this morning we have discovered that this actually seems to relate to the Castle NuGet package we are using. When we reference Castle using the latest NuGet package we end up having a reference to the Castle.Core assembly compiled for the .NET Client Profile 4 this reference is the cause of the exception above (Why? I am not entirely sure yet). Changing the reference to the version compiled for .NET 3.5 ensures the tests pass as expected in all scenarios.

Edit: After some more digging there does appear to be a linked issue (which has given us grounds to go back to Microsoft and see what they have to say) Common Language Runtime detected an invalid program error in unit testing

2
Wasn't this an issue with the initial release of .NET 4 too? Perhaps they broke it again...leppie
That's a good call, thanks for the info. I'll take a look on Google around the .NET 4 release and see if I can see something similar. It's a weird one.Alex
From the technet article it could be that MSTest is not running under full trust.leppie
As far as I can tell we are running MSTest with full trust. MStest runs fine if you ask it to run the test on the command line as well. I.e "mstest /testcontainer:<assembly>". Seems to only be in our automated builds and when invoking the test from Visual Studio.Alex

2 Answers

2
votes

I just fixed the same error on one of my collegues computers by deinstalling micrsoft security patch kb2742595 for .net. I guess something is fixed in the security setting and the MSTest runner can't handle the new settings. We do not have Castle.Core installed.

2
votes

I had a similar error, when trying to run tests which used TypeMock. In order to solve the problem I opened up my solution in Visual Studio and selected Test - Edit Test Settings. In the Test Settings dialog I selected Hosts and switched it to Run tests in 64 bit process on 64 bit machine.

Let me know if this helps. If this has nothing to do with your error, let me know and I'll remove my answer.