デバッグ中にイミディエイトウィンドウで変数の内容を確認しようとしたところ、「ガベージ コレクションを実行できない場所で停止したため、式を評価できません。現在のメソッドのコードが最適化されている可能性があります。」というメッセージが表示され、内容を確認することが出来ません。
どうも現象は参照渡しの内容のみ発生する様で、値渡しの内容は確認できるようです。
(全てを確認したわけでは無いですが、概ねそのようです。)
ずっとこの状態というわけではなく、先日までは問題なく内容が確認できていたのですが、最近になってメッセージが表示されるようになりました。
(この間、開発は進んでいるのでコードは追加・編集されています)
このメッセージは何を意味しているのでしょうか?
どのような場合にこのメッセージが表示されるのでしょうか?
・Releaseビルドになっていませんか?
・リビルドしても解決しませんか?
>aetosさん
返答ありがとうございます。
>・Releaseビルドになっていませんか?
なっています。
ずっとReleaseビルドですが問題はありませんでした。
確認したところ、なぜかアクティブソリューション構成だけDebugになっていました。
まず、全てReleaseにしてクリーン後にビルドしましたが現象は変わりませんでした。
次に全てDebugにしてクリーン後にビルドしましたがやはり現象が変わりませんでした。
>・リビルドしても解決しませんか?
リビルドは試してみましたが解決しませんでした。
>>・Releaseビルドになっていませんか?
>なっています。
>ずっとReleaseビルドですが問題はありませんでした。
Release ビルドはデバッグ用の情報が生成されずコードが最適化される為、デバッグが
できないはずです。
IDE のバージョンが書かれていないようですが、自動で切り替わっていたのでは?
http://www.atmarkit.co.jp/fdotnet/dotnettips/750vbconfigsolution/vbconfigsolution.html
>確認したところ、なぜかアクティブソリューション構成だけDebugになっていました。
デバッグできる場所からできない場所に実行ステップが移ったため、
>ガベージ コレクションを実行できない場所で停止したため、式を評価できません。現在のメソッドのコードが最適化されている可能性があります。
と考えるのが普通だけど、そこを知ってる人でも同じような事例に合ったことはあるみたい。
http://bbs.wankuma.com/index.cgi?mode=al2&namber=36231&KLOG=63
そうなると、IDE が自動で切り替える機能が悪影響を及ぼしてるんじゃないかとか疑いたくなりますね。
>特攻隊長まるるうさん
返答ありがとうございます。
バージョンの記載を忘れていました。
VisualStudio2008です。
自動で切り替わっていた点は、もしかするとそうかも知れません。
Releaseでもデバッグ出来ていましたので。
明示的にするため、今後はDebugに設定しておきます。
ただ、今までデバッグで変数の内容確認も次のステップの設定も問題なく出来ていたんですよね。
Debugに変更しても現象が収まらないですし。
仰るとおり、なんとなく何かが悪影響を及ぼしているように思えます。
> Release ビルドはデバッグ用の情報が生成されずコードが最適化される為、
> デバッグができないはずです。
既定の設定では、Release ビルドでもデバッグ情報は生成されるはずです。
それゆえ Release ビルドであっても、ブレークポイントで一時停止させて、
そこからステップ実行させたり、変数の内容を確認したりすることができます。
> リビルドは試してみましたが解決しませんでした。
クリーン & リビルドで解決しない場合は、新規プロジェクトで
テストコードを書いてみて、それでも同じ状況になるか確認してみてください。
新規プロジェクトでは問題無いのであれば、それぞれのプロジェクトの
設定を順に比較していってみて下さい。その逆に、新規プロジェクトでも
同じ状況になるのであれば、[ツール]-[設定のインポートとエクスポート]で
設定をリセットしてみましょう。
> 先日までは問題なく内容が確認できていたのですが
それ以降、下記のいずれかを変更していたりはしませんか?
・プロジェクト プロパティの[デバッグ]タブにある、"デバッガを有効にする"の
[Visual Studio ホスティング プロセスを有効にする] (Debug 既定値=Off、Release既定値=Off)
・プロジェクト プロパティの[コンパイル]タブにある、"詳細コンパイル オプション"の
[デバッグ情報を作成] (Debug 既定値=Full、Release既定値=pdb-only)
・プロジェクト プロパティの[コンパイル]タブにある、"詳細コンパイル オプション"の
[最適化を有効にする] (Debug 既定値=Off、Release既定値=On)
・[デバッグ]-[例外]で表示される例外ダイアログの内容
・[ツール]-[オプション]で表示されるオプションダイアログの "デバッグ"-"全般" の内容
・[ツール]-[オプション]で表示されるオプションダイアログの "デバッグ"-"シンボル" の内容
> どうも現象は参照渡しの内容のみ発生する様で、値渡しの内容は確認できるようです。
参照渡しという事は、メソッドの ByRef 引数のみが問題になる、という事でしょうか。
確認できなくなるのは、メソッドを呼び出している最中ですか? (呼ばれた側で変数の内容を表示できない)
それとも、メソッドを呼び出した後ですか? (呼び出した後で、参照渡しした変数の内容が表示できなくなる)
>クリーン & リビルドで解決しない場合は、新規プロジェクトでテストコードを書いてみて、それでも同じ状況になるか確認してみてください。
>新規プロジェクトでは問題無いのであれば、それぞれのプロジェクトの設定を順に比較していってみて下さい。その逆に、新規プロジェクトでも同じ状況になるのであれば、[ツール]-[設定のインポートとエクスポート]で設定をリセットしてみましょう。
この二つはまだ未実行です。
>それ以降、下記のいずれかを変更していたりはしませんか?
>・プロジェクト プロパティの[デバッグ]タブにある、"デバッガを有効にする"の[Visual Studio ホスティング プロセスを有効にする] (Debug 既定値=Off、Release既定値=Off)
→ONだが、他の開発環境でもON
>・プロジェクト プロパティの[コンパイル]タブにある、"詳細コンパイル オプション"の[デバッグ情報を作成] (Debug 既定値=Full、Release既定値=pdb-only)
→Releaseでpdb-only
>・プロジェクト プロパティの[コンパイル]タブにある、"詳細コンパイル オプション"の[最適化を有効にする] (Debug 既定値=Off、Release既定値=On)
→ReleaseだがOFF
>・[デバッグ]-[例外]で表示される例外ダイアログの内容
→変更無し
>・[ツール]-[オプション]で表示されるオプションダイアログの "デバッグ"-"全般" の内容
→変更無し
>・[ツール]-[オプション]で表示されるオプションダイアログの "デバッグ"-"シンボル" の内容
→何も設定なし
>参照渡しという事は、メソッドの ByRef 引数のみが問題になる、という事でしょうか。
>確認できなくなるのは、メソッドを呼び出している最中ですか? (呼ばれた側で変数の内容を表示できない)
それとも、メソッドを呼び出した後ですか? (呼び出した後で、参照渡しした変数の内容が表示できなくなる)
→
参照渡しの場合と記載しましたが、正確には「Public Class」で宣言している情報です。
<Serializable()> Public Class TestCls
〜
End Class
Public Test as New TestCls
上記のように宣言している変数「Test」の中の情報を参照しようとするとメッセージが表示されるようになりました。
複数人で開発しておりVSS2005で共有しているのですが、一部の環境では現象が発生していません。
ここと比べて調べてみます。
魔界の仮面弁士様、失礼いたしました。
お礼を書き忘れていました。
お時間を割いていただきありがとうございます。
訂正:
> [Visual Studio ホスティング プロセスを有効にする] (Debug 既定値=Off、Release既定値=Off)
共に On が既定値です。
> 参照渡しの場合と記載しましたが、正確には「Public Class」で宣言している情報です。
「参照渡し」ではなく、「参照型」という事でしょうか。
> 一部の環境では現象が発生していません。ここと比べて調べてみます。
何かわかったらフィードバックをお願いします。
なお、そのエラーは CORDBG_E_ILLEGAL_IN_OPTIMIZED_CODE というもので、
英語版環境では下記のメッセージで表示されるようです。
Cannot evaluate expression because a thread is stopped at a point
where garbage collection is impossible, possibly because the code is
optimized.
以下、可能性は低いけど情報の提供ということで追記しておきます。
VS2003の時代の話だけど、リビルドしただけじゃ出力フォルダ(bin)の情報が
何か残るようで、長期の開発してるとおかしな動きをするようになりました。
その時は、bin および obj フォルダを物理的に削除して、ソースファイルのみの
状態にしてビルドしたら正常に戻りました。
>複数人で開発しておりVSS2005で共有
VSS に新規でフォルダごと入れて、個人の設定ファイル(vbproj.userとか)も
管理してるプロジェクトをたまに見るけど、個人で内容が異なるファイルを
共有するとファイル同士の整合性が取れなくなる場合があるかも。
(Release ビルドの詳細設定がどこに保存されているかまで知らないですが)
まぁ、それの目星をつけるのが
>新規プロジェクトでは問題無いのであれば、それぞれのプロジェクトの〜
なんだろうけど。
結局、ある人は現象が発生せず、私は発生するという事ではありませんでした。
ある処理を実行したとき、フラグで二つのファンクションに振り分けます。
共に、処理が正常に終了したかをBooleanでリターンします。
それぞれのファンクションで冒頭の変数宣言を行うところにブレークポイントを設定。(Dim AAA As Short = 0 となっているところ)
片方のファンクションではブレークポイントでPublicで宣言している変数の内容が見れるのに、もう片方では現象が発生するという状況でした。
もはやお手上げです。
結局、インシデントを使用してマイクロソフトに問い合わせることにしました。
また何かわかれば書き込みます。
原因が判明しました。
引数のサイズが256バイトを越える場合に発生するそうです。
メソッドA内で別のメソッドBに対して256バイト以上の引数を渡す処理がある場合に現象が発生するとのことでした。
これは.net FrameWork2.0コンパイル機能の限界だそうです。
また、現象はデバッグ時に発生する現象であって、アプリケーションとしては問題は発生しないそうです。
対処法は、256バイト以上の引数は値渡しではなく参照渡しにすれば問題が無くなります。
サポートからの回答では、引数で渡している構造体をクラスとして定義すれば参照型になるので現象が回避されるとの事でした。
試したところ、メソッドBで引数をByRefで受けることでも回避できました。