トップ回答者
Visual Studio 2015 ステップ実行が進まない

質問
-
Visual Studio 2015 CommunityをWindows 10 Pro 64bitで使用しています。
.Net フォーム アプリケーションで、BackgroundWorker.DoWorkイベント内でブレークポイントで停止させた後、
F10やF11キーを押しても次のステートメントへステップしません。
その状態でCtrl+Alt+Breakを押すと、そのブレークポイントを指す場合と、
Program.Main()のApplication.Runの位置で停止する場合があります。(条件はわかりません。)
VS2013やVS2010では問題なく動いていたのですが、VS2015で動かないのは何故なのでしょうか。
関連があるかどうかわかりませんが、VS2010で作成しVS2013→VS2015へと移行したプロジェクトなので、構成マネージャ上のプラットフォームはAny CPUではなくx86になっています。
回答
-
以下のいずれかで改善しませんか?
- 「プロジェクトのプロパティ->デバッグ->VisualStudioホスティングプロセスを有効にする」のチェックを外す。
- デバッグ無しで開始(Ctrl+F5)してからデバッガをアタッチする。
- デバッグ時に「ローカル」「自動変数」「ウォッチ」ウィンドウ」を表示しない。(Formクラスの変数を表示しない)
- 「ツール->オプション->デバッグ->全般->変数ウィンドウのオブジェクトに対して文字列変換関数を呼び出す」のチェックを外す。
最後の「変換ウィンドウのオブジェクトに対して文字列変換関数を呼び出す」で何か問題があって、別スレッドにあるフォームの内容の読み取り失敗して、デバッガのブレークポイントが働かなくなっているっぽい?
Ctl+Alt+Breakで中断したときにランダムなのは、メインスレッドで止まるか、ワーカースレッドで止まるかはそのタイミングで有効なスレッドのいずれかがランダムで選択されるからでしょうね。
2015でだけなるのは2015の内部実装が何か変更されたからとしか。
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答の候補に設定 星 睦美 2015年9月30日 2:56
- 回答の候補の設定解除 Yuki Nishina 2015年10月3日 23:48
- 回答としてマーク Yuki Nishina 2015年10月6日 14:37
-
昨日はそれをできたつもりでいたようですが、うまく条件を満たせていなかったようです。
手元でも再現しまして、そのときに「マイコードのみ表示」を OFF にするとおおよそメカニズムが読めました。どうやら、BackgroundWorker のスレッドで this の ToString を実行しようとして、メインスレッドがフォームを表示しようとしている瞬間だからスレッド間でデッドロックを起こしているような感じですね。
Visual Studio のデバッガーの実装の違いに起因するものと予想されます。回避的には、「Load イベントでそういった処理を書くのをやめる」、あるいは「何もしない ToString のオーバーライドを用意する」でしょうか。
オーバーライドとしては public override string ToString() { return string.Empty; } とでもしておくと、現象が起きなくなります。
(Form クラスというよりは、Control クラスの ToString メソッドがウィンドウハンドルを元にウィンドウテキストを取得する実装であるため、デッドロックを引き起こすのであれば、差し障りのない文字列を返せばよいということで、string.Empty を返す実装を入れて回避するというもの)
このような回避をしたくないという話であれば、Microsoft の有償サポートに問い合わせて、HotFix を作ってもらうという具合になるかと思います。
(ただし、それなりの上位のサポートでないと、HotFix 作成は依頼できません)
参考
- 編集済み AzuleanMVP, Moderator 2015年10月5日 15:29
- 回答としてマーク Yuki Nishina 2015年10月6日 14:15
すべての返信
-
以下のいずれかで改善しませんか?
- 「プロジェクトのプロパティ->デバッグ->VisualStudioホスティングプロセスを有効にする」のチェックを外す。
- デバッグ無しで開始(Ctrl+F5)してからデバッガをアタッチする。
- デバッグ時に「ローカル」「自動変数」「ウォッチ」ウィンドウ」を表示しない。(Formクラスの変数を表示しない)
- 「ツール->オプション->デバッグ->全般->変数ウィンドウのオブジェクトに対して文字列変換関数を呼び出す」のチェックを外す。
最後の「変換ウィンドウのオブジェクトに対して文字列変換関数を呼び出す」で何か問題があって、別スレッドにあるフォームの内容の読み取り失敗して、デバッガのブレークポイントが働かなくなっているっぽい?
Ctl+Alt+Breakで中断したときにランダムなのは、メインスレッドで止まるか、ワーカースレッドで止まるかはそのタイミングで有効なスレッドのいずれかがランダムで選択されるからでしょうね。
2015でだけなるのは2015の内部実装が何か変更されたからとしか。
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答の候補に設定 星 睦美 2015年9月30日 2:56
- 回答の候補の設定解除 Yuki Nishina 2015年10月3日 23:48
- 回答としてマーク Yuki Nishina 2015年10月6日 14:37
-
ご回答ありがとうございます。
- 「プロジェクトのプロパティ->デバッグ->VisualStudioホスティングプロセスを有効にする」のチェックを外す。
- デバッグ無しで開始(Ctrl+F5)してからデバッガをアタッチする。
- 「ツール->オプション->デバッグ->全般->変数ウィンドウのオブジェクトに対して文字列変換関数を呼び出す」のチェックを外す。
以上の作業では、正常に動作しました。
- デバッグ時に「ローカル」「自動変数」「ウォッチ」ウィンドウ」を表示しない。(Formクラスの変数を表示しない)
「ローカル」と「自動変数」を非表示にすると正常に動作しました。「ウォッチ」は表示に関わらず変化しません。
又、全ての作業(有効化/無効化)をVS2013 Communityでも実施しましたが、こちらでは不具合は発生しません。
尚、ステップできない状況に陥る時には、ブレークした時に操作可能になるまで5~6秒時間がかかっています。
-
Visual Studio 2015ではデバッグ時に「ローカル」か「自動変数」を表示すると上記現象が発生するのは何故なのでしょうか?
第三者が再現できるサンプルを提示してください。
新規のプロジェクトで再現できるのであれば、作成手順や書いたコードを共有してください。
もしかしたら、その再現用のサンプルに基づいて何らかの推測が寄せられる可能性はあります。
(あくまで、推測であり、あなたが遭遇している事象と一緒かどうかはわかりません)第三者が再現できない事象について、「なぜ起きるのか?」と問われて答えることができるひとはほとんどいません。
どうしてもその謎を解明したいのであれば、Microsoft の有償サポートを検討してみてください。
ただし、その場合でも Microsoft 側で再現できる状態に持って行く必要はあります。// フォーラムはサポートではありません。
// あなたがお困りのことを解決するための義務を負う人はいないので、自分から情報を出していく必要があります。 -
ご回答ありがとうございます。
以下に手順を記載します。
1.フォーム アプリケーション(C#)を新規作成する
2.ツールボックスからBackgroundWorkerを配置する
3.BackgroundWorkerに以下のようなDoWorkイベント ハンドラを作成する
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { int a = 0; int b = 1; }
5.int a = 0;の部分にブレークポイントを設定する。
6.フォームに以下のようなLoadイベント ハンドラを作成する
private void Form1_Load(object sender, EventArgs e) { backgroundWorker1.RunWorkerAsync(); }
7.「プロジェクトのプロパティ->デバッグ->VisualStudioホスティングプロセスを有効にする」のチェックを入れておく
「ツール->オプション->デバッグ->全般->変数ウィンドウのオブジェクトに対して文字列変換関数を呼び出す」のチェックを入れておく8.デバッグを実行する。(自動変数を表示させておく)
9.ブレーク ポイントで停止したら、F10、F11、F5等を押す
10.以降のステートメントが実行されない…
このような現象です。よろしくお願い致します。
-
昨日はそれをできたつもりでいたようですが、うまく条件を満たせていなかったようです。
手元でも再現しまして、そのときに「マイコードのみ表示」を OFF にするとおおよそメカニズムが読めました。どうやら、BackgroundWorker のスレッドで this の ToString を実行しようとして、メインスレッドがフォームを表示しようとしている瞬間だからスレッド間でデッドロックを起こしているような感じですね。
Visual Studio のデバッガーの実装の違いに起因するものと予想されます。回避的には、「Load イベントでそういった処理を書くのをやめる」、あるいは「何もしない ToString のオーバーライドを用意する」でしょうか。
オーバーライドとしては public override string ToString() { return string.Empty; } とでもしておくと、現象が起きなくなります。
(Form クラスというよりは、Control クラスの ToString メソッドがウィンドウハンドルを元にウィンドウテキストを取得する実装であるため、デッドロックを引き起こすのであれば、差し障りのない文字列を返せばよいということで、string.Empty を返す実装を入れて回避するというもの)
このような回避をしたくないという話であれば、Microsoft の有償サポートに問い合わせて、HotFix を作ってもらうという具合になるかと思います。
(ただし、それなりの上位のサポートでないと、HotFix 作成は依頼できません)
参考
- 編集済み AzuleanMVP, Moderator 2015年10月5日 15:29
- 回答としてマーク Yuki Nishina 2015年10月6日 14:15
-
詳しい解説ありがとうございます。
Visual Studioのフィードバックには報告致しました。
とりあえず回避することはできそうなので、あとはアップデートに期待します。
P.S.
Loadイベントからの呼び出しでなくても、発生するようです。- 編集済み Yuki Nishina 2015年10月6日 14:42