.NET Framework 4.6環境でx64アプリケーションが正しく動作しないことがある

概要

.NET Framework 4.6を導入した環境、あるいは.NET Framework 4.6が標準でインストールされているWindows 10において、.NET Framework 4 ~ 4.5.2までを対象としたx64アプリケーション、.NET Framework 4.6を対象としたx64アプリケーションは期待通りに動作しないことがあります。

原因

.NET Framework 4.6を導入すると.NET Framework 4系のx64ビルドしたアプリケーションは新しいRyuJITが使用されるようになります。
しかし、このRyuJITにはネイティブコード生成の不具合、最適化の不具合がいくつか存在しており、アプリケーションが強制終了する、機能が正しく動かないといったアプリケーションの不具合を生じさせるリスクがあります。

この現象は.NET Framework 4 ~ 4.5.2までを対象にリリースした既存アプリケーションであっても、実行環境に.NET Framework 4.6を導入するか、Windows 10に既存アプリケーションをインストールすることで不具合が起きる可能性がある点、他人事とは言えない事情があります。

(Windows 10はWindows 7/8.1から無償アップグレードできるの気づかぬうちに動かなくなるとか、Visual Studio 2015インストールで勝手に入ってしまうとか)

事例情報

以下のMSDNの.NET BlogでRyuJIT最適化に関する不具合について言及されています。

RyuJIT Bug Advisory in the .NET Framework 4.6

このほか、最適化を抑制してもunsafeコードで正しくないメモリ参照を引き起こす不具合が存在しているようです。(業務的に知り得たことなので細かいことは割愛します)

対象外

以下のアプリケーションはこの問題にあたりません。

  • .NET Framework 3.5 SP1 (3.5.1) およびそれ以前を対象とするアプリケーション
  • x86指定でビルドしているアプリケーション
  • .NET Frameworkを使用していないアプリケーション

回避策

運用環境が特定少数、制御可能な範囲であれば.NET Framework 4.6をインストールしないことです。

ただ、不特定多数の市場に向けたアプリケーションの場合はそういった制御ができませんので、RyuJITを無効化することで回避することを考えます。
詳しいことはgithubのページを参照していただきたいですが、おおよそ以下の選択肢があることになります。

  1. app.configに書く。(〇〇.exeであれば、〇〇.exe.configができることになる)
    runtimeセクションに<useLegacyJit enabled="1" />を書き加える。
  2. 環境変数COMPLUS_useLegacyJitに1を設定する
  3. レジストリ(SOFTWARE\Microsoft\.NETFramework)にuseLegacyJitというDWORDの値を作り、1と書き込む。
    HKEY_LOCAL_MACHINEか、HKEY_CURRENT_USERのいずれかでよい。

これから新規に配布する、あるいはアップデートをリリースする予定のアプリケーションであれば、app.config路線が良いでしょう。これであれば、他のアプリケーションに影響を与えません。
次点として、アップデート予定がなく、エンドユーザーのフォローが必要となる場合は、HKEY_CURRENT_USERのレジストリに書くようなregファイルを作った方がユーザーサポートという観点ではやりやすいかもしれません。

回避策の有効性を確認する方法

デバッグ実行していただいて、読み込まれたDLLの一覧をVisual Studioやプロセスエクスプローラーなどで確認してください。
通常はclrjit.dllが読み込まれますが、上記の回避策を打つとcompatjit.dllが読み込まれるようになります。

“.NET Framework 4.6環境でx64アプリケーションが正しく動作しないことがある” への1件の返信

  1. ピンバック: .NET Framework 4.6 の RyuJIT の不具合がいくつか修正されてリリースされている | Azulean's Note @ WordPress.com