System.InvalidProgramException when executing unit tests in MSTest after Microsoft Security update MS13-004
Asked Answered
S

2

6

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

Sesquicentennial answered 29/1, 2013 at 8:16 Comment(4)
Wasn't this an issue with the initial release of .NET 4 too? Perhaps they broke it again...Montpelier
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.Sesquicentennial
From the technet article it could be that MSTest is not running under full trust.Montpelier
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.Sesquicentennial
C
2

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.

Conney answered 29/1, 2013 at 15:38 Comment(4)
Thanks, it is good to know that we are not the only ones experiencing the issue and that Castle.Core is not the only assembly affected (in our case it appears to be the .NET Client Profile 4 compiled Castle.Core reference that MSTest is having issues with). Unfortunately removing the patch is not a real option for us (currently). We have a work around but it would be nice to know exactly what the cause is because I get nervous when I can make something work without really understanding what is going on.Sesquicentennial
In our case there is an securty check in one of our own libs which causes the test runner to fail. Castle.Core can do something simulair as our lib. However it seems that the test runner is not running with the right security settings.Conney
Did you file a bug at microsoft?Conney
We are in the process of getting it raised.Sesquicentennial
S
2

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.

Sextuplet answered 11/2, 2013 at 14:53 Comment(3)
This is something we found as well. It helped in some of our test projects but not them all for some reason. I couldn't figure out why it would suddenly make a difference looking at the notes for the patch that was applied.Sesquicentennial
In VS 2012, this setting is Test -> Test Settings -> Default Processor Architecture -> X64Polygynist
I also had this issue and found it was related to TypeMock not playing nicely in VS2013. The above fix didn't work for me but it led me to a fix that did - uninstalling TypeMock (if you're not using it anymore) or updating it to the latest - I used the last link on this forum page forums.typemock.com/viewtopic.php?f=4&t=22477 (posted Wed Mar 26, 2014 10:02 am)Tericaterina

© 2022 - 2024 — McMap. All rights reserved.