XamlTask​​Factoryでの神秘的なMSBuildクラッシュとの戦い

私たちのチームは、Visual Studio 2015、gcc 4.9以上を搭載したLinux、MacOS、iOS、Android、およびWindows Phone 8.1以降のWindowsでビルドする必要があるクロスプラットフォームアプリケーションカーネルを開発しています。 Jenkinsのコードを自動的に確認するために、必要なすべての構成に対してアセンブリが構成されます。 アセンブリのタスクは、1つまたは複数のプラットフォームで収集されない、または単体テストに合格せず、対応する修正を行う前に最終アプリケーションのチームに到達できないコードをキャッチすることです。 このようなCIプロセスにより、開発者は便利なオペレーティングシステムと開発環境をローカルで使用できます。VisualStudio、Xcode、QtCreator、vim + ninjaなど、変更が収集されないことや別の環境でテストがスローされることを恐れることはありません。



理想的な世界では、Jenkinsの赤いアセンブリ(ビルドサーバーとしての役割で使用されているのは彼です)は、コードの問題を示しています。 部屋の隅にぶら下がっているモニターの赤信号を見て、「アセンブリアシスタント」が問題を解決します。 実際には、ビルドが失敗した理由は非常に異なる場合があります。たとえば、コンパイルが行われたノードとの接続の切断、ディスク領域の不足、またはエイリアンの到着などです。 このような誤検知は、チームから不必要な時間を奪い、注意を鈍らせ、一般的にチーム内のCIに対する信頼を低下させます。 これらの問題の1つに対する闘争の物語を伝えたいです。



問題はMSBuildに固有のものであり、ログに次のようなものが表示されました。



20:03:56 "D:\jenkins\workspace\task\ws\...\SomeTarget.vcxproj" (default target) (429) -> 20:03:56 (_QtMetaObjectCompilerH target) -> 20:03:56 D:\jenkins\workspace\task\ws\...\SomeQtBasedTarget.targets(52,5): error MSB4175: The task factory "XamlTaskFactory" could not be loaded from the assembly "Microsoft.Build.Tasks.Core". Could not find file 'D:\jenkins\workspace\task\ws\TEMP\fv5nnzin.dll'. [D:\jenkins\workspace\jenkins\workspace\task\ws\...\SomeTarget.vcxpro]
      
      





しばらくの間、問題は数日おきに頻繁に発生することはなかったため、私は呪われ、落ちたビルドをもう一度再開しました。 しかし、virtualoksから新しい光沢のあるハードウェアノードに移行した後、状況は悪化し、ランダムなドロップが1日に数回発生する可能性がありました。 この状況は、プロジェクトを構築するために長い間、最終的に容認できませんでした(数十分、ところで、私たちは並行して戦いました)。 CIを介して緊急の修正を実行することが必要な場合もありましたが、多くの時間を待ってから転倒する可能性があったため、再度待つ必要がありました。



それで、何がエラーにつながったのでしょうか?



プロジェクトを生成するには、 gypを使用します 。これには、ビルド中に外部コマンドを呼び出す2つの方法があります-これらはアクションルールです。 アクションは、vcxprojファイル内のCustomBuildを通じて実装されます。



ドキュメントの例:



 <ItemGroup> <CustomBuild Include="faq.txt"> <Message>Copying readme...</Message> <Command>copy %(Identity) $(OutDir)%(Identity)</Command> <Outputs>$(OutDir)%(Identity)</Outputs> </CustomBuild> </ItemGroup>
      
      





そして、それらですべてがうまく、彼らは爆発しません。 ルールは異なるメカニズムを使用します。 コード内のコメントは次のとおりです。

MSBuildルールは、XMLファイル、.targetsファイル、および.propsファイルの3つのファイルを使用して実装されます。 blogs.msdn.com/b/vcblog/archive/2010/04/21/quick-help-on-vs2010-custom-build-rule.aspxを参照してください。


どのように機能しますか? そのようなルールごとに、MSbuild in%TEMP%はC#ソース(.csファイル)を生成し、そこからdllをコンパイルしてすぐに使用しようとします。動作しない場合は、例外をスローします

コメントは言う:

これは、アセンブリのコンパイルに失敗した場合に発生します。 以下の失敗を処理するため、通過します。


実際、(buildserverログによる)エラーの数秒前のシステムログで、次のようなC#コンパイラエラーレコードを見つけることができます。



 Faulting application name: csc.exe, version: 4.6.1055.0, time stamp: 0x563c1a09 Faulting module name: KERNELBASE.dll, version: 6.3.9600.18233, time stamp: 0x56bb4ebb Exception code: 0xc0000142 Fault offset: 0x00000000000ecdd0 Faulting process id: 0x1af4 Faulting application start time: 0x01d1d13dbec0f5bd Faulting application path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe Faulting module path: KERNELBASE.dll Report Id: fc6cf36d-3d30-11e6-8260-0cc47ab21249 Faulting package full name: Faulting package-relative application ID:
      
      





Googleで同様のエラーを検索したところ、非対話型セッションのデスクトップヒープのサイズであることが示唆されました。 実際、エラーコードは一致し、JenkinsスレーブエージェントはWindowsサービスとして機能しました。



この仮説を開発に取り込んで、レジストリエントリHKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ SubSystems \ WindowsのSharedSectionセクションの値をいじり始めました。 その過程で、偶然にアセンブリがほぼ100%の確率でクラッシュしやすくなり、デバッグの反復が多少容易になりました。 もう少し読んだ後、Jenkinsサービスプロパティの[デスクトップとの対話を許可する]チェックボックスに移動し、HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ WindowsのNoInteractiveServicesオプションに移動しました。 しかし、これらすべての試みは実を結びませんでした。 ビルドが成功することもありましたが、パターンをキャッチできませんでした。



Jenkinsサービスの下で実行中のプロセスの機能を引き続き調べて、StackOverflowで次のテキストに出会いました。 著者は、MSBuildに複数のプロジェクトを並行してビルドするために/ Mオプションを指定した場合のMSBuildのデフォルトの動作の特性について話しています。 一番下の行は、MSBuildが自分自身の適切な数のコピーを作成することです-ノードはタスクを待機しています。 アセンブリプロセス中、タスクはこれらのノードに散在し、並行して実行されます。 アセンブリが完了した後、ノードは急冷されず、新しいタスクを待ち続けます。 これはJenkinsでも発生し、ビルドが完了した後、MSBuildプロセスがメモリでハングし続けました。



私は実験を始めました。 ビルドの落下を数回連続で再現した後、メモリ内にあるすべてのMSBuildプロセスを強制終了しました。見よ、次のビルドは成功しました。 次に、StackOverflowを使用した命令で武装し、変数MSBUILDDISABLENODEREUSEを設定し、MSBuild呼び出しに/ nr:falseオプションを転送するビルドスクリプトに追加しました。 その後、すべてのMSBuildプロセスはアセンブリの終わりに死に始め、メモリに残りませんでした。



ソリューションは機能していることが判明しました。 ほぼ2週間が経過しましたが、問題は再現されていません。 そして、エラーの根本原因を完全には理解していませんでしたが、機能する解決策を見つけることができました。



All Articles