2013 年 1 月 8 日に Microsoft セキュリティ更新プログラムhttp://technet.microsoft.com/en-us/security/bulletin/ms13-004を適用した後、ビルド サーバー上およびローカルで CI ビルドに失敗するようになりました。開発ボックスでテストを実行しています。
System.InvalidProgramException: Common Language Runtime detected an invalid program が発生します。
これは、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());
}
これにより、DynamicProxy で MixinData コンストラクターを呼び出すときに例外がスローされるスタック トレースが生成されます。
Castle.DynamicProxy.MixinData..ctor(IEnumerable`1 mixinInstances) Castle.DynamicProxy.ProxyGenerationOptions.Initialize() Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode(Type proxyTargetType、Type[] インターフェイス、ProxyGenerationOptions オプション) 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 コンテキスト、Object[] コンストラクター引数) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstance(CreationContext コンテキスト、ConstructorCandidate コンストラクター、Object[] 引数) Castle.MicroKernel. ComponentActivator.DefaultComponentActivator.CreateInstance(CreationContext コンテキスト、ConstructorCandidate コンストラクター、Object[] 引数) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.Instantiate(CreationContext コンテキスト) Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext コンテキスト) Castle.MicroKernel.ComponentActivator.AbstractComponentActivator .Create(CreationContext コンテキスト、負担) Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext コンテキスト、Boolean trackedExternally) Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.Resolve(CreationContext コンテキスト、IReleasePolicy releasePolicy) Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext コンテキスト、Boolean requiresDecommission、Boolean instanceRequired、負担 & 負担) Castle.MicroKernel. Handlers.DefaultHandler.Resolve(CreationContext コンテキスト、Boolean 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);
MSTest ランナーの外では、すべてが期待どおりに機能し、アプリケーションは引き続き機能し、xUnit または MSTest を使用して TestDriven.NET で単体テストを実行しても、例外は生成されません。この動作は、Visual Studio からテストを実行するか、TFS と自動ビルド用の MSBuild スクリプトを使用する場合にのみ見られます。
Microsoft にサポート チケットを提出する前に、他の誰かが同様のことを経験したか、または問題の原因について何か考えがあるかどうかを尋ねようと思いましたか?
編集:今朝いくつかの新しいことを調べた後、これが実際に使用している Castle NuGet パッケージに関連しているように見えることがわかりました。最新の NuGet パッケージを使用して Castle を参照すると、最終的に.NET Client Profile 4用にコンパイルされた Castle.Core アセンブリへの参照が作成されます。この参照が上記の例外の原因です (なぜですか? まだ完全にはわかりません)。.NET 3.5 用にコンパイルされたバージョンへの参照を変更すると、すべてのシナリオでテストが期待どおりに合格することが保証されます。
編集:さらに掘り下げた後、リンクされた問題があるようです(これにより、マイクロソフトに戻って彼らの意見を確認する根拠が得られました)共通言語ランタイムは、ユニットテストで無効なプログラムエラーを検出しました