連載
» 2010年07月21日 00時00分 公開

フレッシュマン企画 連載 簡単!Visual Studio 2010入門:第6回 Windowsアプリケーションのデバッグ&リリース (4/5)

[一色政彦,デジタルアドバンテージ]

■VS 2010によるアプリケーションのデバッグ方法

 デバッグの基本は、問題となっている可能性の高い個所のコードを1ステップ(=1文)ずつ追跡して調べていくことである。それを行うには、怪しいと思われる個所の一歩手前でプログラムの実行を一時的に停止させる必要がある。このプログラムの実行を一時停止する機能を「ブレークポイント」と呼ぶ。このデバッグ方法は、例えていうならば、DVDビデオを一時停止して(=ブレークポイント)、そこからコマ送りで再生する(=1ステップずつ追って調べる)という操作に似ている。

 今回のプログラムで問題となっている可能性の高いコードは、先ほど追加したフェード・アウトのコードだ。そこで、menuItemClose_Clickメソッドの中にあるFormFadeOutメソッドにブレークポイントを仕掛けてみることにしよう。次の画面は、実際にブレークポイントを設定しているところだ。

ブレークポイントの設定
menuItemClose_Clickメソッドの中にあるFormFadeOutメソッドにブレークポイントを設定したところ。ブレークポイントを設定するには、該当行にカーソルを移動し、[F9]キーを押すだけである(もしくは左端の赤いの部分をクリックしてもよい)。逆に、ブレークポイントを解除する場合も[F9]キーを押せばよい。もし複数個所に設定したブレークポイントを一括解除したい場合には、[Ctrl]+[Shift]+[F9]キーを押せばよい。

 ブレークポイントを設定したら、[F5]キーを押すか、メニュー・バーから[デバッグ]−[デバッグ開始]をクリックして、デバッグ実行を開始する。

 デバッグが開始されると「時計」アプリケーションが起動するので、右クリックでコンテキスト・メニューを表示して[終了]を実行してみよう。すると、次の画面のようにブレークポイントを設定した位置で処理が停止するはずだ。

ブレークポイントの位置で処理が停止した画面
ブレークポイントを設定したFormFadeOutメソッドの呼び出し位置で処理が停止したところ。停止している個所は黄色の矢印で示されている。

 処理を1ステップ(=1文)進めるには、[F10]キーを押す(「ステップ・オーバー」と呼ばれる)。また、メソッド内の処理に入るには、[F11]キーを押す(「ステップ・イン」と呼ばれる)。ここでは、FormFadeOutメソッド内部の処理を調べたいので、ステップ・インの[F11]キーを押す。すると、次の画面のように、FormFadeOutメソッドの内部に移って処理が停止する。

ステップ・インしたメソッド内で処理が停止した画面
[F11]キーを押して、FormFadeOutメソッド内部に入って処理が停止したところ。
  (1)FormFadeOutメソッドの実装開始部分(「{」の場所)で処理が停止している。停止している個所は黄色の矢印で示されている。
  (2)[呼び出し履歴]ウィンドウ(「コール・スタック」とも呼ばれる)。[呼び出し履歴]ウィンドウを表示するには、メニュー・バーから[デバッグ]−[ウィンドウ]−[呼び出し履歴]を選択すればよい。このウィンドウでは、現在の処理がどういう順番で呼び出されたのかが分かる。例えばこの画面では、最初に「MyClock.exeのMyClock名前空間のDisplayクラスのMainメソッド」が呼ばれ、その次に「DisplayクラスのmenuItemClose_Clickメソッド」が呼ばれ、最後に「FormFadeOutメソッド」が呼ばれているということが分かる。この画面の例は単純だが、メソッドの呼び出しが複雑な場合、この[呼び出し履歴]ウィンドウが役立つことがある。[呼び出し履歴]ウィンドウ内のメソッドをダブルクリックすれば、そのメソッド呼び出しの該当行にジャンプできる。

 次に[F10]キーでステップ・オーバーして、FormFadeOutメソッドの処理を1ステップずつ進めていってみよう。すると、forループの間をぐるぐると繰り返し実行しているのが分かるだろう。ここで、forループ内にある、変数「n」の値やOpacityプロパティの値がバグの原因として疑わしいので、どうなっているか調べてみよう。これを調べるには、次の画面のように[ウォッチ]ウィンドウを使う。

[ウォッチ]ウィンドウによる変数状態の確認
[ウォッチ]ウィンドウで変数の状態を確認しているところ。[ウォッチ]ウィンドウを表示するには、メニュー・バーから[デバッグ]−[ウィンドウ]−[ウォッチ]−[ウォッチ 1]を選択すればよい。
  (1)[ウォッチ]ウィンドウで調べたい変数やプロパティ、メソッドなどを選択して(ダブルクリックで単語を選択できる)、[ウォッチ]ウィンドウ内にドラッグ&ドロップする。
  (2)[ウォッチ]ウィンドウに追加された変数やプロパティの値は、処理を1ステップ進めるごとにリアルタイムに更新される。
  (3)変数やプロパティの上にマウス・カーソルを乗せることで、その変数やプロパティの状態をツール・チップで表示することもできる。

 [ウォッチ]ウィンドウで変数「n」の値を参照すると、「49」から減るはずの値が「51」と逆に増えている。つまりforループのコードで、カウント・アップ(=インクリメント)するのは間違いなのだ(「n++」は1つずつカウント・アップするという意味)。

for (int n = 49; n >= 0; n++)

forループでカウント・アップする間違ったコード

 正しくは、次のようにカウント・ダウン(=デクリメント)しなければならなかったわけだ(「n--」は1つずつカウント・ダウンするという意味)。

for (int n = 49; n >= 0; n--)

forループでカウント・ダウンする正しいコード

 このコーディング・ミスにより、プログラムは無限に(厳密には数値の範囲があるので有限だが……)カウント・アップし続け、アプリケーションがフリーズした(「応答なし」の)状態になっていたわけだ。

 バグの個所が判明したので、[Shift]+[F5]キーを押すか、メニュー・バーから[デバッグ]−[デバッグの停止]を選択するかして、デバッグ実行を終了する。そして、先ほどのforループのコードの誤りを修正して、再ビルドを行い実行してみよう。すると、次は正常にフェード・アウトしながら、アプリケーションが終了するはずだ。

 以上でプログラムは完成した。せっかく作ったので、このプログラムを実際にユーザーに使ってもらえるようにしてみよう。次に、プログラムのリリースと配布について簡単に解説しておく。

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。