■掲示板に戻る■ ■過去ログ倉庫めにゅーに戻る■
デバッグテクニックあれこれ
1 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 18:33
何かライブラリを使った方法とか、
条件コンパイルの定石だとか、
デバッグのことについて教えてくれ。



2 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 18:44
gオプション


3 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 18:52
printfばらまき


4 名前: 1 投稿日: 2001/04/04(水) 18:54
>>2
うむ。で、GDB かね。

>>3
うむ。よくやる。

次。



5 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 18:56
C++ の テンプレートってどうやって駄馬具するの?


6 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 19:04
UnitTest


7 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 19:08
よくSTLのバグなんて発見するよな


8 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 19:09
メモリリークのチェックをする為に
プロファイルを行い、mallocとfreeの呼出し回数が
一致しているか調べる
# reallocしている場合、一致しないかもしれない



9 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 19:13
素直にデバッガ使え。


10 名前: エラー 0、警告 0 投稿日: 2001/04/04(水) 19:20
エラー 0、警告 0


11 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 19:21
warning level 4でビルド



12 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 19:23
TRACE()ばらまき


13 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 19:25
TRON/TROFF
でばっちり


14 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 19:26
printf


15 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 19:28
プリントアウトして気丈デバッグ。


16 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 19:35
>>11
VC++のSTLが量産する警告を何とかしちくり。


17 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 19:35
ダウジングと心眼。


18 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 19:40
>>8
せめて malloc, realloc, strdup, free のラッパ関数
書いてチェックすれ。

メモリ周りのデバッグツールのリンク集
http://www.cs.colorado.edu/homes/zorn/public_html/MallocDebug.html

Purify 使ってる人いたら評価を聞いてみたいんだけど。



19 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 19:47
>>16
#pragma warning(disable:4786 4788)
を使うべし


20 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 19:55
>>18
Purify使う事あるけど、物すごく遅い。
まぁでもリークは見えないものをめっけてくれる。
でもそれくらいかなぁ。


21 名前: 名無しさん 投稿日: 2001/04/04(水) 20:36
MSJの付録についてたLodPrf32は良い。
VisualStudioをインストールしていない
ターゲットマシン上で起動した
EXEのデバッグ文字列と
DLLの実行時リンクのトレースを表示する
ことができるツール。



22 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 21:28
少々のアルコールを摂取すると大変効果的。


23 名前: デフォルトの名無しさん 投稿日: 2001/04/04(水) 22:10
assertで全ての引数を範囲チェック。



24 名前: デフォルトの名無しさん 投稿日: 2001/04/05(木) 00:01
printf( "[%64s][%04d]",__FILE__ ,__LINE__ );
で十分


25 名前: デフォルトの名無しさん 投稿日: 2001/04/05(木) 00:08
リリース前に一度 "if" でgrepする。
if(a==b) と書いたつもりが if(a=b) になっていたら
結構発見しにくいバグになってしまう。
大量に引っかかるけど気合でチェック。


26 名前: 名称未設定 投稿日: 2001/04/05(木) 00:12
根性!根性!根性!


27 名前: デフォルトの名無しさん 投稿日: 2001/04/05(木) 00:53
>>6
前々から気になってる。
具体例キボンヌ。


28 名前: 6>27 投稿日: 2001/04/05(木) 01:16
たとえばint max(int a, int b)という関数を作成した場合、
あわせて
void test_max(void)
{ // もちろん実際はもっと手を抜く
 assert(2, max(2,1)); // 第一引数が大きい場合
 assert(2, max(1,2)); // 第二引数が大きい場合
 assert(2, max(2,2)); // 同値である場合
 assert(2, max(-2,2)); // 負数を含む
 assert(2, max(2,-2)); // 負数を含む
 assert(2, max(-2,-2)); // 負数で同値
assert(INT_MAX, max(INT_MAX, INT_MIN)); // 境界をチェック
}
というチェック関数を書く。
そして、こまめにこのチェック関数を実行する。
# 実際はassertではなくUnitTest支援ツール・ライブラリを使う
高速化したらチェック。
コンパイラが変わったらチェック。
(maxが依存している)intcmpを変更したらチェック。
maxの仕様が変わったら(あるいはテストを書き換えて)チェック。
バグがあったら、そのバグを再現させるassertを追加してチェック。
なにもしなくても一日一回はチェック。
ひたすらチェック。
チェックに一つでも失敗したら、それを直してから先へ進む。

これをアプリ全体のモジュール・クラス(の全てのメソッド)に対して適用すると、
(チェックした範囲内で)100%正しく動くアプリが完成する。
100%正しく動いているアプリは拡張も変更も容易。-> リファクタリング等々

参照
http://objectclub.esm.co.jp/eXtremeProgramming/


29 名前: デフォルトの名無しさん 投稿日: 2001/04/05(木) 01:39
UNIXでmalloc関係だと、electric fenceがお手軽で好き。


30 名前: 27 投稿日: 2001/04/05(木) 02:07
>>28
解説サンクス!
試してみるね。
そういえば、monazillaのところでも同じことやってたみたい。
>参照
おおお。テスティングフレームワークが一杯!


31 名前: デフォルトの名無しさん 投稿日: 2001/04/05(木) 09:59
未だにcoreの使い方がわからんのだが
誰か簡単に教えて〜ん


32 名前: デフォルトの名無しさん 投稿日: 2001/04/05(木) 10:07
>>31
gdb a.out core
(a.outはcore吐いたプログラム名)

詳しい説明は以下を読め
http://www.asahi-net.or.jp/%7Ewg5k-ickw/html/online/gdb-4.18/gdb_toc.html


33 名前: 31 投稿日: 2001/04/05(木) 13:27
あんがと。
それSolarisでも使える?


34 名前: デフォルトの名無しさん 投稿日: 2001/04/05(木) 13:34
>>33
OSじゃなくて、開発環境に依存する。
gdbはGNUだけ。


35 名前: Solaris 投稿日: 2001/04/05(木) 13:39
dbxでできたよ
(あんまり詳しくないんで聞き返さないで)



36 名前: デフォルトの名無しさん 投稿日: 2001/04/05(木) 19:45
>>25
だから警告レベルを上げろっての。


37 名前: デフォルトの名無しさん 投稿日: 2001/04/11(水) 01:15
assertのばら撒き方で厨房か否かが判別できるな。
>23はやりすぎ。
assert撒かないのや存在そのものを知らない奴は論外。


38 名前: デフォルトの名無しさん 投稿日: 2001/04/11(水) 01:36
>>36
拾ってくれないコンパイラーも有るかも。
もしかしたら。

VCの場合、最高に警告レベルあげたら、使っていない引数まで
律儀に表示した...

WinMainの引数なんて instanceくらいしかつかわんのに (..;



39 名前: デフォルトの名無しさん 投稿日: 2001/04/11(水) 03:04
>>38
C++ 限定ですが、関数定義に引数の型だけ書くことで警告を抑制
できます。

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, int)
{
  // do something
}


40 名前: デフォルトの名無しさん 投稿日: 2001/04/11(水) 04:11
>>37
そのへんの判別基準がまだよくわからない厨房ですが、参考になる
書籍とか Web とかありませんか?

Eiffel の事前条件とか事後条件とかのイメージで assert を入れる
のはどうなんでしょう?


41 名前: デフォルトの名無しさん 投稿日: 2001/04/11(水) 04:34
>>38

使っていない引数を明示的に示すマクロは存在する。

UNREFERENCED_PARAMETER(param)

でも展開されると param = param なだけだけど。


42 名前: デフォルトの名無しさん 投稿日: 2001/04/11(水) 09:39
>>40
契約による〜 だと、assert はドキュメンテーションの
感覚だからあながち 23 もやりすぎとは言えないかも知れない。
個人的には、不正な値を渡すと assert するまでもなく落ちるような場合
(null とか)は入れないなあ。見逃すとヤバい系(配列の添字とか)は
チェックしてます。


43 名前: デフォルトの名無しさん 投稿日: 2001/04/11(水) 10:20
>41
(void)param;
じゃだめだったっけ?


44 名前: 弱い者の味方、 投稿日: 2001/04/11(水) 11:54
月光仮面おじさん登場!!!
ホームページを作ったものの、まったくアクセスが上がらな
くて悩んでいる人のためにお役に立ちましょう。
効率よく宣伝できる共有宣伝掲示板を18個設置しました。
全部宣伝して回ればなんと1,000以上の掲示板にカキコしたこ
とになり即、効果が期待できます。さらに共有掲示板の隠し
リンクを発見してそれらも全部宣伝して回ると計2,000以上の
掲示板にカキコしたことになり、さらにアクセスアップを期
待できます。もう、今日からアクセスが無くて悩むことは無
いです。今すぐここからアタックアタック!!

http://home9.highway.ne.jp/cym10262/


45 名前: デフォルトの名無しさん 投稿日: 2001/04/11(水) 20:04
>>39
おー なるほど、そんな手があったんですね ^^;
サンクス。
今度試してみます


46 名前: デフォルトの名無しさん 投稿日: 2001/04/12(木) 03:19
でもやっぱり変数をprintしまくる事が一番ラクで一番確実だと思う。
効率悪いけど、コンパイルが速いDelphiだと充分実用範囲だったりするし。


47 名前: デフォルトの名無しさん 投稿日: 2001/05/02(水) 07:19
リリースにもOutputDebugStringを仕込みっぱなし


48 名前: デフォルトの名無しさん 投稿日: 2001/05/02(水) 11:00
カーネルのデバッグでgdbを使いたいんだけど
どうすればいい?

やりたいのはデバイスモジュールのデバグだから
それ単体で試験できるならカーネル全体はいらないけど


49 名前: デフォルトの名無しさん 投稿日: 2001/05/02(水) 13:11
>>46
printf debugにコンパイルスピードが関係するの?


50 名前: デフォルトの名無しさん 投稿日: 2001/05/02(水) 13:21
#ifdef hogehoge
#define DEBUG_ASSERT(result, message)
#else
#define DEBUG_ASSERT(result, message) { if(!result) { put_log(message); exit_app(); } }
#endif

こんなのを複数個作って
エラーの種類によって入れたり外したりしてる・・


51 名前: デフォルトの名無しさん 投稿日: 2001/05/03(木) 21:18
あげるよ〜


52 名前: ななしぃ 投稿日: 2001/05/03(木) 22:51
VC++ならウォッチウィンドウにEAXだな


53 名前: ななしぃ 投稿日: 2001/05/03(木) 22:52
あと、_asm int 3 ってのも場合によっては最強の手段


54 名前: デフォルトの名無しさん 投稿日: 2001/05/03(木) 23:27
シリアルとかネットワークでリモートからgdb使えば…
って対象カーネルは何者よ?


55 名前: 48 投稿日: 2001/05/03(木) 23:36
>>54
ふつうのLinuxです
自作のデバイスドライバでgdb上でステップ実行したいところとか
あるんで上手いやり方ないかなあ と。


56 名前: デフォルトの名無しさん 投稿日: 2001/05/03(木) 23:55
gcc or g++用の
ユニットテストツールってどこにありますか?


57 名前: デフォルトの名無しさん 投稿日: 2001/05/03(木) 23:57
既述でしたすんまそんsage


58 名前: デフォルトの名無しさん 投稿日: 2001/05/04(金) 00:25
>>55
http://kgdb.sourceforge.net でどう?
二台いるけど。


59 名前: デフォルトの名無しさん 投稿日: 2001/05/04(金) 01:26
ちなみに、真紀俊夫のCマガジンの連載「ローテク講座」の
第1回は
printfをデバッグが終わったあとにはずすと自動変数の初期化の関係で潜在的バグが現れる
という(なんとも低レベルな)話だった。


60 名前: 48 投稿日: 2001/05/04(金) 01:30
>>58
うはー英語だー
日本語訳はなさそうですね。
kgdb、少し勉強してみます。訳したらここに貼り付けましょうか?


61 名前: デフォルトの名無しさん 投稿日: 2001/05/04(金) 01:35
http://pesuo.hypermart.net/michiroh/denpatoh/index.html
うんこ投げてー


62 名前: 名無しさん 投稿日: 2001/05/05(土) 08:28
いろんなバグを出せば、その内バグのパターンが分かってくるので
ツールなんかいらなくなる。動作を見れば一瞬で分かるようになる。

デバッグじゃなくてバグチェックの話だとすると、
近代科学社の「ソフトウェア・テストの技法」
という本も参考になる。古いけど、チェック技法について
広く網羅している。


63 名前: デフォルトの名無しさん 投稿日: 2001/05/05(土) 11:16
traceとか
#ifdef DEBUGとか
assertとか
がいっぱい入ってると メンテ、するとき
読みづらくてこまる。
なんとかならないのかな


64 名前: デフォルトの名無しさん 投稿日: 2001/05/05(土) 12:33
>>63
traceとか
#ifdef DEBUGとか
assertとか

を削除するスクリプト作ってみてはいかが?
ソース閲覧用に。


65 名前: デフォルトの名無しさん 投稿日: 2001/05/05(土) 19:36
>>62
バッファオーバーランとか、メモリリークとか、共有リソースロックし忘れ
とか、バグの理由はわかるようになっても、その発生個所はわからんだろ。
シングルスレッドアプリならまぁ、わからんでもないか。


66 名前: デフォルトの名無しさん 投稿日: 2001/05/05(土) 20:45
外注アプリのメニューでデバッグとかトレースとかって
残ってるの見るとちょっとどうかと。


67 名前: デフォルトの名無しさん 投稿日: 2001/05/09(水) 16:20
>>66
だって取ると傷つきそうなんだもん。