- ベストアンサー
現場のデバック方法
はじめまして。これまで私がデバックを行っていた方法として、あやしいところにprintf()を使って表示させて、バグが取り除けたらprintf()を消すという原始的な方法でしてきました。最近になって条件つきコンパイルやデバッカーを使うようになり、デバックも少しずつ楽になってきました。そこで実際にソフトウェア開発に携わったことのある方やその辺りの知識のある方にお伺いしたいのですが、どのようなデバックをなされているのでしょうか? (1)printf()を使う。 (2)条件つきコンパイルや組み込みマクロを使う。 #ifdef DEBUGや__DATE__などetc (3)デバッカーを使う。 私はemacs上でgdbを使っています。 (4)その他 ちなみに私の開発環境は ・プログラミング言語 : C言語 ・OS : FreeBSD ・エディタ : emacs ・コンパイラ : gcc です。 C言語以外のプログラミング言語での意見でも構いませんのでご意見をよろしくお願い致します。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは、honiyonです。 私はログファイルを生成するように設計しています。 βリリースまでは常に出力するようにし、正式リリースでは、条件付コンパイルでoffにするか、又は起動時オプションで、 /d を指定すれば出力出来るようにしています。 後者であれば、納品後に不具合が発生した時に、その現場の環境でログが採取出来るので便利です。 この仕組みがバグの温床になるリスクは極めて低いので有効です。 ログ用の関数を1つ用意するだけです。 あと、中~大規模プロジェクトで有効なのが、デバッグ用プログラムを作成することです。 各関数に対して、いくつかの条件で呼び出し、その結果が正しいかを判断する為のプログラムです。 たとえば、足し算をする関数に対して、 printf("1+2..."); int answer = add_func(1,2); if (answer == 3 ) { printf("ok\n"); } else { printf("error. answer is %d\n", answer); } なんて感じで行います。 大規模プロジェクトでは、基本となる関数が大量に出来てくるでしょうし、複数人で開発するので、知らぬうちに矛盾が発生してバグとなっている事があります。 また、仕様変更が関数を編集する必要が出た場合も必要なテストを一発で再テストする事も出来ます。 面倒だから、最低限の再テストだけすればいいや~、で、実は重大なバグを見逃した、という事がありません。 この方法の問題は、テストプログラムの作成に時間がかかる、という事です。 なので小規模には不向きと思います。 因みにこの方法はLinuxのカーネル開発に用いられています。他のプログラムでも見かけますね。 makeコマンドで自動チェックを行えるようになっているものがあります。 後はCVS等でしっかりとバージョン管理を行えば良いと思います。 この辺の考え方を基本として、TPOに応じて使い分けたり、応用したりする事が最適だと思います。 参考になれば幸いです(..
その他の回答 (6)
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> デバッカーが最後の手段とはどういう意味なんでしょうか? 安易にデバッガに頼るな。バグのほとんどはデバッガ無しにデバッグできる、と考えています。 # 'デバック'ではありません。'デバッグ'(debug)です。
お礼
たびたび回答ありがとうございます。 ×デバック ○デバッグ ×デバッカー ○デバッガ なんですね。今まで勘違いしていました。 また私の大学の教授がバグがあるとすぐデバッガを使えと言われていたので、安易にデバッガを使おうとしていたのですが、以後デバッガは最終手段と肝に銘じてプログラミングをしていこうと思います。 どうもありがとうございました。
- sha-girl
- ベストアンサー率52% (430/816)
大規模な開発になると デバッグ用の関数をもたせることはやります。 特にマルチスレッドで動くプログラムは同期状態がよくわからないので 共通の時間を取得してファイルに出力したりしています。 もちろんリリース版には残したくないのでコンパイルされないようにします。 ※gdbは最終手段でアセンブラレベルでみたいときや レジスタの値を参照したい時に使ってます。 #2の回答はコンシュマー開発のときはディスプレイが別なので有効ですが CUIな画面がインターフェースなら使えませんね。やはりファイル出力します。 バグがでたら出力したファイルの値から だいたい位置が特定できると思うのでその辺にブレークはって あとはステップイン、ステップアウトの繰り返し。 アセンブラレベルでステップすれば、取り除けないバグは無いはず・・・ ちなみにVC++だと ::OutputDebugString(char *)というものがあらかじめ用意されています。 これは#2の回答のdbgのような感じで リリース版ではコンパイルされません。
お礼
たびたび回答ありがとうございます。 大規模開発などは今の私の身の回りでは縁がありませんが、非常に考え方が参考になりました。 これを機会にデバッグ用の関数を作成したりしてみようと思います。どうもありがとうございました。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
(4.1) assert を使う (4.2) UnitTestFramework でテストコードを書く デバッガは'最後の手段'と肝に銘じています
お礼
回答ありがとうございます。初めて聞く用語で知らなかったのですが、(4.1)(4.2)を調べてみようと思います。デバッカーが最後の手段とはどういう意味なんでしょうか?もしお時間がありましたら回答をお願いします。どうもありがとうございました。
- tama_2001
- ベストアンサー率18% (21/111)
こんにちは。 他の方の回答を読んでいたら、#3さんが近いかも。 「デバッグ=コンパイルが通った直後のブツを試験」ならば 私の場合、gdb(またはdbx)ですね。 JAVA なら jdb(笑) 条件付コンパイルではデバッグは行いません。 いままでにデバッグ用のプログラムを作ったのは、 関数に呼ばれる関数が呼ぶ関数の・・・と 呼ばれる先の、システムコールを呼ぶ関数に対してだけでした。 それ以外の関数のデバッグ時は、期待した値を返すダミー関数を用意して。 (インタフェースは本物と同一です) お互いのデバッグが終わってリンクした後にも ちゃんと試験は行いますけど、それも dbx や gdb や jdb デシタ。 gdb から入った私には jdb は苦でもなんでもないのですが、 「ソースコードとにらめっこしながら行う」作業は 苦痛な人が多いのかもしれません。 ちなみに、printfは「どっかがおかしいけどドコだよ!!!」という バグ追い時に「とりあえず入れてみよー♪ハハハ。」と 入れることはありますが、納品時は削除しています。 ログ出力用の関数は用意されているし、 ブツを起動する人は画面とにらめっこしてません。 (24時間365日、人間を貼り付けてはおけません) 逆にお客様の目に簡単に入ってしまうエラーは マズイのです・・・(^^;
お礼
JAVAだとjdbなんですね(笑)あとやはりデバック用の関数を現場では使うものなんですね。とても参考になりました。どうもありがとうございました。
- sha-girl
- ベストアンサー率52% (430/816)
printfをわざわざ消すなんてことはしません。 #if defined(_DEBUG) #define dbg(...) \ (printf("%s %u @%s:",__FILE__,__LINE__,__func__), \ printf(" "__VA_ARGS__)) #else #endif のようにdbgでも定義してやれば、 _DEBUGのdefineをはずすだけで、dbgはコンパイル されませんし 上記のように行番号や関数名、ファイル名もつけておくと便利です。 #define _DEBUG int main(){ int x=0; dbg("x=%d",x); } _DEBUGのdefineをはずすだけですべて、dbgの部分 がコンパイルされなくなります。 _
お礼
回答ありがとうございます。そうですね、やっぱり条件付コンパイルを使ったほうが便利ですよね。大変参考になりました。わかりやすい解説をありがとうございます。
- Tsukasa0215
- ベストアンサー率22% (280/1257)
みんな同じ様な物だと思いますよ(笑)
お礼
私の周りも同じような人ばかりですね(笑)どうも回答ありがとうございました。
お礼
回答ありがとうございます。とても参考になりました。規模が大きくなるとデバック用の関数も作成するのは初めて聞きました。makeコマンドで自動チェックやCVSもまだまだ浅はかな知識しか持ち合わせていないので勉強したいと思います。どうもありがとうございました。