トップ回答者
NVIDIA Quadro + VisualStudio 2013 で不安定動作

質問
-
状況説明
OpenGLを使用したアプリケーション(32bit)を開発・メンテナンスしています。- 当アプリケーションを、今年 VisualStudio C++ 2008 から VisualStudio C++ 2013 へ変更しました。
- 一部の環境で、アプリケーションが不安定(クラッシュなど)になる問題が発生しました。
-
問題
- クラッシュ(異常終了)
- ダイアログが一瞬開くが、直ぐに閉じる。
- ファイルを開いた際に、「ファイル名が長すぎます」のエラーが出る。
- など
- 調査したところ、環境が以下の場合に発生していました。
- グラフィックボード = NVIDIA Quadro
- 上記以外の場合は、問題は発生していない。(Intel HD, NVIDIA GeForce)
- 暫定対処
Microsoftの情報
MicrosoftサポートWeb(以下のURL)に、関係すると思われる情報がありました。
- 英語:https://support.microsoft.com/en-us/help/2894215/you-experience-performance-issues--product-crashes--or-rendering-issue
- 日本語:https://support.microsoft.com/ja-jp/help/2894215/you-experience-performance-issues--product-crashes--or-rendering-issue
- VisualStudio 2013 以降で発生
- グラフィックスドライバーのバグの可能性あり
お願い
現在のところ、VisualStudio C++ 2008 に戻すと問題が発生しない事より、VisualStudio C++ 2013 の問題と 思っていますが、原因や対処方法などの詳しい情報を教えて頂きたい。
(取りあえずは、上記の暫定対処で問題を回避していますが、 一部DLLをVisualStudio C++ 2008で作るのは面倒ですし、 他システムのサポートの問題もあります。)
- 編集済み Katsumi Goto 2017年11月10日 10:03
回答
-
Quadroを搭載していた環境で問題が発生したとのことですが、グラフィックスハードウェア(とグラフィックスドライバー)以外の条件(OS、CPUやメモリなど)は完全に同じなのでしょうか? 対照実験の原則に基づいて論理的に検証していますか? ミスリードやバイアスを引き起こすタイトルは避けるべきです。
また、質問をするときは最低限のマナーとして、検証したハードウェアの型番や、デバイスドライバーのバージョンも示すようにしてください。OSのバージョンなども示すべきです。
ちなみにアプリケーションの開発にはMFCか何かのフレームワークを使っているのでしょうか? Visual Studio 2013には最新のアップデート(Update 5)を適用していますか? また、OpenGLの想定バージョンはいくつですか? もしGLEWを使っている場合、バージョンはいくつですか?
すでにほかの回答者の方から説明がなされていますが、ID 2894215のサポート記事は、Visual Studio自身の画面描画に関する問題の回避策に関するものです。Visual Studioは2010以降、画面描画の一部にWPF (Direct3D) を導入しているため、グラフィックスドライバーにバグがあるとVisual Studio自身のパフォーマンスが低下したりクラッシュしたりすることがあります。
なお、「プラットフォームツールセットの変更」という回避策が提示されていますが、それだと結局コンパイルには旧コンパイラおよび旧SDKが使われることになり、VS2013を使う意義が薄れます。恒久的な解決策というよりは、開発環境移行時の一時的・過渡期的な用途でのみ利用するのがよいと思います。
ところで、Visual C++ 2012以降は、x86 (32bit) プラットフォームの場合コンパイルオプション/arch:SSE2が既定で使われるようになっています。SSE2命令をサポートしない古いCPUでは問題を起こす可能性があります。
https://msdn.microsoft.com/en-us/library/7t5yh4fd(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/7t5yh4fd(v=vs.100).aspx
Visual C++ 2013にて、まず/arch:IA32を試してみてください。プロジェクトのプロパティから、[構成プロパティ]→[C/C++]→[コード生成]→[拡張命令セットを有効にする]を、「拡張命令なし (/arch:IA32)」に設定することで、コンパイラはSSE/SSE2命令を使わなくなります。とはいえ、x64対応しているCPUはすべてSSE2に対応しているので、よほどの骨董品でもないかぎり/arch:SSE2が問題を起こすことはありませんが。
他にも、一部の最適化オプションを無効化することで、正常動作するようになる可能性もあります。旧コンパイラが生成したコードでは一切問題が起きないとのことなので、QuadroグラフィックスドライバーのバグというよりはVCコンパイラが引き起こした問題である可能性が高いのではないでしょうか。
- 編集済み sygh 2017年11月11日 9:27
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年11月13日 0:49
- 回答としてマーク Katsumi Goto 2017年12月5日 9:14
-
まず、ドライバを最新にしてみるべきかもしれません。
次に、改善策ではありませんが、対象DLLのプロジェクトののプロパティDLGの「構成プロパティ」の「全般」の中に、「プラットホームツールセット」があります。
これを「Visual Studio 2013(v120)」から「Visual Studio 2008(v90)」にした場合にはどうなりますでしょうか。
これで症状が出ないのであれば、少なくともVS2013でビルドすることができ、
作業上の煩わしさはなくなると思われます。
なお、掲載されたページはVS自体に対する設定であり、ビルドされる実行ファイルには関係ないと思われます。- 編集済み 仲澤@失業者 2017年11月10日 9:59
- 回答としてマーク Katsumi Goto 2017年12月5日 9:14
すべての返信
-
まず、ドライバを最新にしてみるべきかもしれません。
次に、改善策ではありませんが、対象DLLのプロジェクトののプロパティDLGの「構成プロパティ」の「全般」の中に、「プラットホームツールセット」があります。
これを「Visual Studio 2013(v120)」から「Visual Studio 2008(v90)」にした場合にはどうなりますでしょうか。
これで症状が出ないのであれば、少なくともVS2013でビルドすることができ、
作業上の煩わしさはなくなると思われます。
なお、掲載されたページはVS自体に対する設定であり、ビルドされる実行ファイルには関係ないと思われます。- 編集済み 仲澤@失業者 2017年11月10日 9:59
- 回答としてマーク Katsumi Goto 2017年12月5日 9:14
-
グラフィックスドライバを、NVIDIA社Webサイトの最新に変更しましたが、解決しませんでした。
「プラットホームツールセット」は、試してみます。
返信ありがとうございます。
- 編集済み Katsumi Goto 2017年11月10日 10:14
-
Quadroを搭載していた環境で問題が発生したとのことですが、グラフィックスハードウェア(とグラフィックスドライバー)以外の条件(OS、CPUやメモリなど)は完全に同じなのでしょうか? 対照実験の原則に基づいて論理的に検証していますか? ミスリードやバイアスを引き起こすタイトルは避けるべきです。
また、質問をするときは最低限のマナーとして、検証したハードウェアの型番や、デバイスドライバーのバージョンも示すようにしてください。OSのバージョンなども示すべきです。
ちなみにアプリケーションの開発にはMFCか何かのフレームワークを使っているのでしょうか? Visual Studio 2013には最新のアップデート(Update 5)を適用していますか? また、OpenGLの想定バージョンはいくつですか? もしGLEWを使っている場合、バージョンはいくつですか?
すでにほかの回答者の方から説明がなされていますが、ID 2894215のサポート記事は、Visual Studio自身の画面描画に関する問題の回避策に関するものです。Visual Studioは2010以降、画面描画の一部にWPF (Direct3D) を導入しているため、グラフィックスドライバーにバグがあるとVisual Studio自身のパフォーマンスが低下したりクラッシュしたりすることがあります。
なお、「プラットフォームツールセットの変更」という回避策が提示されていますが、それだと結局コンパイルには旧コンパイラおよび旧SDKが使われることになり、VS2013を使う意義が薄れます。恒久的な解決策というよりは、開発環境移行時の一時的・過渡期的な用途でのみ利用するのがよいと思います。
ところで、Visual C++ 2012以降は、x86 (32bit) プラットフォームの場合コンパイルオプション/arch:SSE2が既定で使われるようになっています。SSE2命令をサポートしない古いCPUでは問題を起こす可能性があります。
https://msdn.microsoft.com/en-us/library/7t5yh4fd(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/7t5yh4fd(v=vs.100).aspx
Visual C++ 2013にて、まず/arch:IA32を試してみてください。プロジェクトのプロパティから、[構成プロパティ]→[C/C++]→[コード生成]→[拡張命令セットを有効にする]を、「拡張命令なし (/arch:IA32)」に設定することで、コンパイラはSSE/SSE2命令を使わなくなります。とはいえ、x64対応しているCPUはすべてSSE2に対応しているので、よほどの骨董品でもないかぎり/arch:SSE2が問題を起こすことはありませんが。
他にも、一部の最適化オプションを無効化することで、正常動作するようになる可能性もあります。旧コンパイラが生成したコードでは一切問題が起きないとのことなので、QuadroグラフィックスドライバーのバグというよりはVCコンパイラが引き起こした問題である可能性が高いのではないでしょうか。
- 編集済み sygh 2017年11月11日 9:27
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年11月13日 0:49
- 回答としてマーク Katsumi Goto 2017年12月5日 9:14
-
Katsumi Goto さん、こんにちは
フォーラム オペレーターの立花楓です。
本件についてその後いかがでしょうか。無事に問題は解決されましたでしょうか。
何か進展がございましたらこちらのスレッドへご返信いただけますと幸いです。また、お寄せいただいた情報が参考になった場合には [回答としてマーク] をお願いいたします。
よろしくお願いします。
MSDN/TechNet Community Support 立花楓
-
返信ありがとうございます。また私の返信が遅くなり、申し訳ありません。
お問合せ頂いた内容について、以下に報告します。
PC環境
- PC: CELSIUS W520, NVIDIA Quadro 4000(ドライババージョン:21.21.13.7761)
- OS: Windows 10 バージョン1703
Q/A
- Q: MFCか何かのフレームワークを使っているか?
- A: MFCは使用しています。
- Q: Visual Studio 2013には最新のアップデート(Update 5)を適用しているか?
- A: 適用しています。
- Q: OpenGLの想定バージョンいくつか?
- A: 想定バージョンは分かりませんでした。
OpenGLの想定バージョンで気になる点があれば教えてください。
- Q: Visual C++ 2012以降は、コンパイルオプション/arch:SSE2が既定値に変更された。
- A: CPUはSSE2に対応していますので、関係ないと思われます。
-
推測を基にした情報から回避策を求めるのではなく、まずは事実を基にした原因究明を行うべきでは?
つまり、何が原因でこの問題が発生しているのか、そこを明確にする必要があると思います。
該当アプリがクラッシュしているのであれば、アプリケーション ログにクラッシュ時のエラー情報が残っているはずです。
この情報を確認するだけで、原因箇所を特定できる場合もあります。アプリケーション ログからの原因究明が難しい場合は、とりあえず下記調査を行い、どのような経緯で AppCrash が起きているのか確認してみては?
--------------------------------------
<調査方法の提案>1. WER でアプリケーション クラッシュ時にプロセス ダンプを採取する設定を行い、該当アプリ クラッシュ時のプロセス ダンプを採取して、それを解析する。
++++++++++++++++++++++++++++++
Windows エラー報告を使ってユーザーモードプロセスダンプを取得する方法
https://support.symantec.com/ja_JP/article.TECH233988.html
++++++++++++++++++++++++++++++2. 上記1で根本的な原因究明に至らなかった (例えばメモリ破壊が起きていることが確認できても、その破壊を行っている箇所が特定できない) 場合、Application Verifier (AppVerif.exe) で 該当アプリの検証を行い、問題発生箇所を絞り込む。
++++++++++++++++++++++++++++++
Windows SDK ツール:Application Verifier のご紹介
https://blogs.msdn.microsoft.com/japan_platform_sdkwindows_sdk_support_team_blog/2011/05/29/windows-sdk-application-verifier/
++++++++++++++++++++++++++++++
なお Application Verifier は、デバッグ対象プロセス内に存在する全てのエラーを拾いまくるので、今回の AppCrash とは全く関係ないエラーも拾ってしまうことになります。
なので、チェックする項目をできるだけ絞って検証する必要があります。
-------------------------------------- -
問題の発生しているPCはFujitsu製のワークステーションのようですが、カスタマイズ可能なBTO品のようなので、スペックを提示するときはCPU型番やメモリ容量などの仕様もきちんと掲載してください。ちなみにWindows 10は32bit版ですか? 64bit版ですか? 以前提示した「技術系メーリングリストで質問するときのパターン・ランゲージ」をもう一度よく読んでください。
また、問題の発生していない環境についても、第三者が正しく比較できるようにするため、詳細情報を提示するようにしてください。以前も述べたように、正常動作環境と異常動作環境とで、2つ以上条件が異なるようであれば、対照実験にはなりません。
OpenGLの想定バージョンが分からないとのことですが、WindowsおよびWGLが標準でサポートしているのはOpenGL 1.1までです。Quadro 4000 (Fermiアーキテクチャ) 自体はドライバー348.17以降にてOpenGL 4.5まで対応していますが、Windows上でOpenGL 1.2以降の標準機能および拡張機能を使うためには、wglGetProcAddress()で関数エントリポイントを実行時に取得するか、GLEWなどのユーティリティを使います。もしこれらを一切使っていないということであれば、ターゲットバージョンはOpenGL 1.1ということになりますが、察するにOpenGLやWGLを理解されていないようなので、まずOpenGLとWGLに関して基本を勉強されたほうがよいと思います。テクノロジーを十分理解していないまま使うのは危険です。もしwglGetProcAddress()やGLEWを使っている場合、呼び出し/型キャストや使用方法が不適切なせいで、間接的にメモリ破壊が起きている、という可能性もありえます(古いコンパイラではたまたま上手くいっていたが、新しいコンパイラでは不正なコードを出力する、など)。余談ですが、OpenGLドライバー実装の厳密度や規格準拠レベルはベンダーやハードウェアによって異なり、いいかげんなコードでもなんとか動いてしまうものもあれば、正しく動作しないものもあります。
あとは問題の発生するPCにVS2013開発環境もしくはリモートデバッグ環境をインストールして、デバッグランタイムを使ってデバッグ実行してみるのもひとつの手です。おそらく何らかの不正なC/C++コードを記述している、もしくはC/C++コードとしては正しいもののコンパイラが不正なコードを出力しているせいで、未定義動作を引き起こしているのだと思われますが、少なくともCRT/MFCの管轄内でアクセス違反などがあれば、その時点でデバッグランタイムが検出してくれます。もしCRT/MFCの管轄外でアクセス違反を起こしている場合、複雑骨折した結果が未定義動作の症状として遅れて現れるため、直接的な原因の特定は難しくなるでしょう。C/C++はプログラマーが正しいコードを記述するということを前提とした言語であり、コンパイラよりもプログラマーの責任が重くなっています。
また、VC2013にて、プラットフォームツールセットの変更や、/arch:IA32オプションの使用、あるいは一部の最適化オプションをOFFにすることは実際に試されたのでしょうか? もし試されたのであれば結果の比較報告をしてください。何も試してもいないのに推測だけで判断するべきではありません。拡張命令の使用や最適化が不正なコード出力の原因になっている、ということもありえます。なお、VC2013はC++11規格に概ね準拠していますが、そのためC++98とはコードの解釈が変わってしまうこともあります。VC2013にはgccのようなC++98互換モードは用意されていません。- 編集済み sygh 2017年12月10日 8:32