デバッグ
[1] 主筆嬢 06/06/18 22:01
念のため、目次。
Sun Studio 11のデバッグ周辺の機能について説明してみる。
[2] nabiki_t 06/06/18 22:03
デバッグって、統合開発環境としては結構重要な機能だと思うんだが、何で今までこの話が抜けてたんだ?
[3] 主筆嬢 06/06/18 22:05
それは単に気が向かなかったから。
[4] nabiki_t 06/06/18 22:05
気が向かないとか、そういう問題なのか?
まぁ、それはいいとして、一応このページ内の目次。
[5] 主筆嬢 06/06/18 22:06
で、早速始めるものとして。
まず、デバッグするにはデバッグ対象のプログラムが必要になる。だから、とりあえずこんなものを作ってみた。

プロジェクトの名前はTestPrj4。
処理内容としては、プログラムの実行時に与えられた引数を順番に表示して、最後に"TESTPRJ4"という環境変数の値を表示して終了するだけ。
[6] 主筆嬢 06/06/18 22:08
プログラムを作ったらコンパイルする。

上の絵では自動生成したMakefileを表示しておいたけど、これは別に手書きであっても問題ない。
ただ必ず、コンパイル時のオプションに"-g"が指定されるようにする。そうしないとデバッグできない。
んで、コンパイルする。

[7] 主筆嬢 06/06/18 22:09
ここからが本題。デバッグする。
デバッグするためには、デバッグ対象のプログラムを読み込まなければならない。

左の「エクスプローラー」という画面で、生成した実行プログラムを選択して、右クリックで表示されるメニューから「プログラムを読み込む」を選択する。
あるいは、メニューの「デバッグ(D)」−「プログラムを読み込む(G)...」を選択して、表示されたダイアログから指定してもいい。

[8] 主筆嬢 06/06/18 22:10
プログラムを読み込むと、下図のようなプログレスバーが表示されて、デバッガが起動される。

デバッガが起動すると、画面がこういう風に変化する。

[9] 主筆嬢 06/06/18 22:12
ここで、デバッグの王道であるステップ実行をやってみることにする。
ステップ実行は「デバッグ(D)」−「ステップオーバー(V)」か「ステップイン(I)」を選択すると開始される。


現在実行中の行は、緑色で表示される。
この状態で「ステップオーバー 」や「ステップイン 」を選択すれば、1行ずつ処理が進んでいく。
「継続 」を選択すると、中断しているところから処理が一気に進められる。ブレークポイントに達するか、シグナルを受信するか、処理が終了するまで止まらない。
「プロセスを再実行 」を選択すると、文字通りプロセスを一番初めからやり直すことになる。
[10] nabiki_t 06/06/18 22:14
時々、「継続 」のつもりで「プロセスを再実行 」を連打してて、何かおかしい、どうも変だと思って頭を抱えることがあるんだがな……
[11] 主筆嬢 06/06/18 22:15
そんなのはおまえだけだ。
[12] 主筆嬢 06/06/18 22:18
バカは放っておいて、ブレークポイントを設定してみる。
ブレークポイントを設定するには、メニューの「デバッグ(D)」−「新規ブレークポイント(B)」を選択して、表示されたダイアログで了解を押下する。


あるいはもっと単純に、テキストが表示されている領域の左側にある灰色の部分をクリックしてもいい。
ブレークポイントが設定されると、その行が悪趣味な朱色で表示されるようになる。

[13] 主筆嬢 06/06/18 22:22
今度はプログラムの実行中に、変数の値を見ることを考える。
明らかに画面左側に「ローカル変数」というウインドウがあって、そこに変数名と値が表示されている。
またそれ以外にも、プログラム中の変数名を指定して、設定されている値を表示させる事もできる。
変数名が記述されているところにマウスカーソルを合わせてしばらく放置しておくと、変数の内容が表示される。式の評価結果を表示したい場合には、表示したい範囲を選択してからマウスを合わせればいい。

上の画面だとマウスカーソルは表示されてないけど、一応マウスカーソルは「argv[i]」の部分に合わせてある。
[14] 主筆嬢 06/06/18 22:26
プログラムをデバッグしていると、時々シグナルを受信することがある。セグメント例外だの、バスエラーだの何だのといって実行が阻害されることがある。
まぁ、何分バグがあるからデバッグしているんだけど。
で、そういった事が起きると、下図みたいな画面が表示されて、プログラムの実行が停止される。

ここで「破棄して一時停止」を選択すると、プログラムの停止位置が表示される。

[15] 主筆嬢 06/06/18 22:28
今回のバグの原因は、プログラムの実行時に"TESTPRJ4"という環境変数が定義されていなかったのが原因。
getenv関数は指定された環境変数が定義されていない場合にはNULLを返す。だからプロセスが落ちた。
[16] 主筆嬢 06/06/18 22:30
そういうことで、今度は実行時の引数と環境変数の設定をしてみる。
引数と環境変数を設定するには、メニューの「デバッグ(D)」−「dbg設定(N)...」を選択する。

そうすると、こういうダイアログが表示される。
「TestPrj4 - 設定」というやる気のないタイトルが付いている。

「環境」というタブを選択して、画面上部にある「引数(A):」という部分に、プロセスを起動するときの引数を入力する。
実行時の環境変数は、その下のリストに追加すればいい。
ここでは引数に"abc ABC xyz XYZ"、環境変数のTESTPRJ4には"hogehoge"と指定しておいた。
[17] 主筆嬢 06/06/18 22:33
そして実行する。
画面下部にある「プロセス入出力」というタブを選択すると、標準入出力にアクセスすることができる

ちゃんと引数が渡されて、環境変数の値を参照できているのが分かる。
[18] 広告 06/06/18 22:35
[19] 主筆嬢 06/06/18 22:39
どっかのバカが書き散らかしたプログラムにはバグが多い。突然とんでもないメモリ番地にアクセスしてみたり、メモリリークを発生させてみたりと、枚挙にいとまがない。
[20] nabiki_t 06/06/18 22:39
>>19
あぁ、おまえの書いたプログラムは特に酷いな。
[21] 主筆嬢 06/06/18 22:42
おめーの事だよ。
[22] 主筆嬢 06/06/18 22:45
こういうバカには、メモリの使用検査をやってやるのが有効。
メモリ破壊やリークを検出することができる。
メモリアクセスのエラーを検出は、メニューの「デバッグ(D)」−「メモリー(M)」−「アクセス検査(A)」を選択することで、有効になる。

アクセスエラーのチェックを有効化すると、未初期化のメモリへのアクセス・未割り当てのメモリへの読み込みや書き込みなどを検出できるようになる。
ついでにいうと、これはプロセスの実行中には変更できない。アクセスエラーのチェックの有効化・無効化を切り替えても、「プロセスを再実行 」を行うまでは変更が反映されない。

アクセスエラーの情報は、出力ウインドウの下部にある「アクセスエラー」タブを選択すると表示される。
プロセスの実行中にエラーが検出されると、メッセージが表示され、プロセスの実行が停止される。
[23] 主筆嬢 06/06/18 22:47
メモリリークを検出を有効にするには、メニューの「デバッグ(D)」−「メモリー(M)」−「使用検査(U)」を選択する。
使い方は大体アクセスエラーの時と同じ。検出したエラーやメッセージは、出力ウインドウの下部にある「メモリー使用」タブを選択すると表示される。
メモリリークは、プロセスの実行中には自動的には表示されない。実行中に表示したい場合には、出力ウインドウで右クリックして、表示されたメニューで「新たなリークを表示」を選択する。

メモリブロックの使用状況も同じ。実行中に表示させたければ、出力ウインドウの上部にある「ブロック」タブを選択して、出力ウインドウで右クリックして、表示されたメニューで「全てのブロックを表示」を選択する。

プロセスの実行が終了すると、実際に発生したメモリリークの情報が勝手に表示される。

このとき実行したプログラムでは、for文の前でmallocしておきながら解放していないため、終了したときにリークとして報告された。
[24] 主筆嬢 06/06/18 22:50
ついでにいうと、メモリの使用検査を有効にすると、処理速度が強烈に遅くなる。
どっかのバカの頭の回転速度並みに遅くなる。
[25] nabiki_t 06/06/18 22:53
うるせーよ。
[26] 主筆嬢 06/06/18 22:54
デバッグしてると、特にステップ実行してると、時々実行中にプログラムを書き換えたくなることがある。
一応Sun Studio 11でも、実行中の動的な修正に対応しているから、やろうと思えばできなくはない。
[27] 主筆嬢 06/06/18 22:55
とりあえず、まずは実行してみる。
実行時の引数は"abc ABC xyz XYZ"。環境変数のTESTPRJ4には"hogehoge"を指定してある。

ここで、for文の終了条件"i < argc"を修正して、"i < argc - 2"にする。

そうしたら、変更したファイルを保存して、メニューの「デバッグ(D)」ー「修正(X)」を選択する。

そうすると、出力ウインドウに修正結果が表示される。

で、このまま処理を続行する。

引数は4つ指定したはず(つまりargcは5のはず)なのに、argv[2]までしか表示されていないのがわかる。
[28] 主筆嬢 06/06/18 23:00
まぁ、大体こんなもんかな。
他にもいろいろな機能はあるみたいだけど、今日は疲れたから、もう寝る。
[29] nabiki_t 06/06/18 23:00
あるなら書けよ。まったく……
[30] 名無しさん 06/06/18 23:05
目次はこちら。
|