トップページ⇒tech
67コメント17KB

デバッグテクニックあれこれ

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
何かライブラリを使った方法とか、
条件コンパイルの定石だとか、
デバッグのことについて教えてくれ。
0002デフォルトの名無しさんNGNG
gオプション
0003デフォルトの名無しさんNGNG
printfばらまき
00041NGNG
>>2
うむ。で、GDB かね。

>>3
うむ。よくやる。

次。
0005デフォルトの名無しさんNGNG
C++ の テンプレートってどうやって駄馬具するの?
0006デフォルトの名無しさんNGNG
UnitTest
0007デフォルトの名無しさんNGNG
よくSTLのバグなんて発見するよな
0008デフォルトの名無しさんNGNG
メモリリークのチェックをする為に
プロファイルを行い、mallocとfreeの呼出し回数が
一致しているか調べる
# reallocしている場合、一致しないかもしれない
0009デフォルトの名無しさんNGNG
素直にデバッガ使え。
0010エラー 0、警告 0NGNG
エラー 0、警告 0
0011デフォルトの名無しさん NGNG
warning level 4でビルド
0012デフォルトの名無しさんNGNG
TRACE()ばらまき
0013デフォルトの名無しさんNGNG
TRON/TROFF
でばっちり
0014デフォルトの名無しさんNGNG
printf
0015デフォルトの名無しさんNGNG
プリントアウトして気丈デバッグ。
0016デフォルトの名無しさんNGNG
>>11
VC++のSTLが量産する警告を何とかしちくり。
0017デフォルトの名無しさんNGNG
ダウジングと心眼。
0018デフォルトの名無しさんNGNG
>>8
せめて malloc, realloc, strdup, free のラッパ関数
書いてチェックすれ。

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

Purify 使ってる人いたら評価を聞いてみたいんだけど。
0019デフォルトの名無しさんNGNG
>>16
#pragma warning(disable:4786 4788)
を使うべし
0020デフォルトの名無しさんNGNG
>>18
Purify使う事あるけど、物すごく遅い。
まぁでもリークは見えないものをめっけてくれる。
でもそれくらいかなぁ。
0021名無しさんNGNG
MSJの付録についてたLodPrf32は良い。
VisualStudioをインストールしていない
ターゲットマシン上で起動した
EXEのデバッグ文字列と
DLLの実行時リンクのトレースを表示する
ことができるツール。
0022デフォルトの名無しさんNGNG
少々のアルコールを摂取すると大変効果的。
0023デフォルトの名無しさんNGNG
assertで全ての引数を範囲チェック。
0024デフォルトの名無しさんNGNG
printf( "[%64s][%04d]",__FILE__ ,__LINE__ );
で十分
0025デフォルトの名無しさんNGNG
リリース前に一度 "if" でgrepする。
if(a==b) と書いたつもりが if(a=b) になっていたら
結構発見しにくいバグになってしまう。
大量に引っかかるけど気合でチェック。
0026名称未設定NGNG
根性!根性!根性!
0027デフォルトの名無しさんNGNG
>>6
前々から気になってる。
具体例キボンヌ。
00286>27NGNG
たとえば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/
0029デフォルトの名無しさんNGNG
UNIXでmalloc関係だと、electric fenceがお手軽で好き。
003027NGNG
>>28
解説サンクス!
試してみるね。
そういえば、monazillaのところでも同じことやってたみたい。
>参照
おおお。テスティングフレームワークが一杯!
0031デフォルトの名無しさんNGNG
未だにcoreの使い方がわからんのだが
誰か簡単に教えて〜ん
0032デフォルトの名無しさんNGNG
>>31
gdb a.out core
(a.outはcore吐いたプログラム名)

詳しい説明は以下を読め
http://www.asahi-net.or.jp/%7Ewg5k-ickw/html/online/gdb-4.18/gdb_toc.html
003331NGNG
あんがと。
それSolarisでも使える?
0034デフォルトの名無しさんNGNG
>>33
OSじゃなくて、開発環境に依存する。
gdbはGNUだけ。
0035SolarisNGNG
dbxでできたよ
(あんまり詳しくないんで聞き返さないで)
0036デフォルトの名無しさんNGNG
>>25
だから警告レベルを上げろっての。
0037デフォルトの名無しさんNGNG
assertのばら撒き方で厨房か否かが判別できるな。
>23はやりすぎ。
assert撒かないのや存在そのものを知らない奴は論外。
0038デフォルトの名無しさんNGNG
>>36
拾ってくれないコンパイラーも有るかも。
もしかしたら。

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

WinMainの引数なんて instanceくらいしかつかわんのに (..;
0039デフォルトの名無しさんNGNG
>>38
C++ 限定ですが、関数定義に引数の型だけ書くことで警告を抑制
できます。

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, int)
{
  // do something
}
0040デフォルトの名無しさんNGNG
>>37
そのへんの判別基準がまだよくわからない厨房ですが、参考になる
書籍とか Web とかありませんか?

Eiffel の事前条件とか事後条件とかのイメージで assert を入れる
のはどうなんでしょう?
0041デフォルトの名無しさんNGNG
>>38

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

UNREFERENCED_PARAMETER(param)

でも展開されると param = param なだけだけど。
0042デフォルトの名無しさんNGNG
>>40
契約による〜 だと、assert はドキュメンテーションの
感覚だからあながち 23 もやりすぎとは言えないかも知れない。
個人的には、不正な値を渡すと assert するまでもなく落ちるような場合
(null とか)は入れないなあ。見逃すとヤバい系(配列の添字とか)は
チェックしてます。
0043デフォルトの名無しさんNGNG
>41
(void)param;
じゃだめだったっけ?
0044弱い者の味方、NGNG
月光仮面おじさん登場!!!
ホームページを作ったものの、まったくアクセスが上がらな
くて悩んでいる人のためにお役に立ちましょう。
効率よく宣伝できる共有宣伝掲示板を18個設置しました。
全部宣伝して回ればなんと1,000以上の掲示板にカキコしたこ
とになり即、効果が期待できます。さらに共有掲示板の隠し
リンクを発見してそれらも全部宣伝して回ると計2,000以上の
掲示板にカキコしたことになり、さらにアクセスアップを期
待できます。もう、今日からアクセスが無くて悩むことは無
いです。今すぐここからアタックアタック!!

http://home9.highway.ne.jp/cym10262/
0045デフォルトの名無しさんNGNG
>>39
おー なるほど、そんな手があったんですね ^^;
サンクス。
今度試してみます
0046デフォルトの名無しさんNGNG
でもやっぱり変数をprintしまくる事が一番ラクで一番確実だと思う。
効率悪いけど、コンパイルが速いDelphiだと充分実用範囲だったりするし。
0047デフォルトの名無しさんNGNG
リリースにもOutputDebugStringを仕込みっぱなし
0048デフォルトの名無しさんNGNG
カーネルのデバッグでgdbを使いたいんだけど
どうすればいい?

やりたいのはデバイスモジュールのデバグだから
それ単体で試験できるならカーネル全体はいらないけど
0049デフォルトの名無しさんNGNG
>>46
printf debugにコンパイルスピードが関係するの?
0050デフォルトの名無しさんNGNG
#ifdef hogehoge
#define DEBUG_ASSERT(result, message)
#else
#define DEBUG_ASSERT(result, message) { if(!result) { put_log(message); exit_app(); } }
#endif

こんなのを複数個作って
エラーの種類によって入れたり外したりしてる・・
0051デフォルトの名無しさんNGNG
あげるよ〜
0052ななしぃNGNG
VC++ならウォッチウィンドウにEAXだな
0053ななしぃNGNG
あと、_asm int 3 ってのも場合によっては最強の手段
0054デフォルトの名無しさんNGNG
シリアルとかネットワークでリモートからgdb使えば…
って対象カーネルは何者よ?
005548NGNG
>>54
ふつうのLinuxです
自作のデバイスドライバでgdb上でステップ実行したいところとか
あるんで上手いやり方ないかなあ と。
0056デフォルトの名無しさんNGNG
gcc or g++用の
ユニットテストツールってどこにありますか?
0057デフォルトの名無しさんNGNG
既述でしたすんまそんsage
0058デフォルトの名無しさんNGNG
>>55
http://kgdb.sourceforge.net でどう?
二台いるけど。
0059デフォルトの名無しさんNGNG
ちなみに、真紀俊夫のCマガジンの連載「ローテク講座」の
第1回は
printfをデバッグが終わったあとにはずすと自動変数の初期化の関係で潜在的バグが現れる
という(なんとも低レベルな)話だった。
006048NGNG
>>58
うはー英語だー
日本語訳はなさそうですね。
kgdb、少し勉強してみます。訳したらここに貼り付けましょうか?
0061デフォルトの名無しさんNGNG
http://pesuo.hypermart.net/michiroh/denpatoh/index.html
うんこ投げてー
0062名無しさんNGNG
いろんなバグを出せば、その内バグのパターンが分かってくるので
ツールなんかいらなくなる。動作を見れば一瞬で分かるようになる。

デバッグじゃなくてバグチェックの話だとすると、
近代科学社の「ソフトウェア・テストの技法」
という本も参考になる。古いけど、チェック技法について
広く網羅している。
0063デフォルトの名無しさんNGNG
traceとか
#ifdef DEBUGとか
assertとか
がいっぱい入ってると メンテ、するとき
読みづらくてこまる。
なんとかならないのかな
0064デフォルトの名無しさんNGNG
>>63
traceとか
#ifdef DEBUGとか
assertとか

を削除するスクリプト作ってみてはいかが?
ソース閲覧用に。
0065デフォルトの名無しさんNGNG
>>62
バッファオーバーランとか、メモリリークとか、共有リソースロックし忘れ
とか、バグの理由はわかるようになっても、その発生個所はわからんだろ。
シングルスレッドアプリならまぁ、わからんでもないか。
0066デフォルトの名無しさんNGNG
外注アプリのメニューでデバッグとかトレースとかって
残ってるの見るとちょっとどうかと。
0067デフォルトの名無しさんNGNG
>>66
だって取ると傷つきそうなんだもん。
■ このスレッドは過去ログ倉庫に格納されています