SlideShare a Scribd company logo
1 of 52
||д´) ジーッ|⊂| バグベアード入門
バグベアード入門 Boost.勉強会 ( 2009-12-12 )
概要 バグベアードとは? Hello, Bugbeard! 既存のコードへの適用 プロファイリング カバレッジ測定 “悪魔の契約” ご利用に当たってのヒント
バグベアードとは? バグベアード入門
バグベアードとは?(1/5) Boost C++ Libraries とは関係ありません。 Boost 採用に向けて協力してくださる方がいれば検討します。 私の英語力が頼りないので、主にコミュニケーションのサポートをして頂ければ…
バグベアードとは?(2/5) printf デバッギングを簡単且つゴージャスに行う為のヘッダーファイル サンプルおよびドキュメント関係やおまけのアイコンファイルを除けばバグベアードは bug.hだけで、他にはなにもありません 若干のマクロによる指定とともにインクルードするだけ
バグベアードとは?(3/5) バグベアードの機能 プログラム動作ログ出力 プロファイリング機能 カバレッジ測定機能
バグベアードとは?(4/5) etc ライセンスフリー マルチプロセス/マルチスレッド対応 各種ログの出力先、出力形式を自在にカスタマイズ可能 Windows と POSIX な環境に対応 その他の環境(カーネルモード含む)も要望があれば対応を検討します ANSI(MBCS)/Unicode に対応 日本語/英語を切り替え可能 ソースコードレベルで組み込まれるのでユーザー環境でも特殊なツールをインストールしたりすることなくそのまま使用可能
バグベアードとは?(5/5) URL http://tricklib.com/cxx/ex/bugbeard/
Hello, Bugbeard! バグベアード入門
Hello, Bugbeard!(1/19) まずは bug.hをダウンロード http://tricklib.com/cxx/ex/bugbeard/bug.h
Hello, Bugbeard!(2/19) ソースコードにおまじないを記述 #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT       //  "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br />   new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr))                                 //  標準エラーへツリー形式の出力を行うロガーの定義 #else #define BUG_DISABLE_BUGBEARD    //  バグベアードのOFF #endif #include "bug.h"                //  バグベアード本体の include
バグベアードを有効にする為のマクロ定義 (※後半の”悪魔の契約”にて説明) #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT       //  "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br />   new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr))                                 //  標準エラーへツリー形式の出力を行うロガーの定義 #else #define BUG_DISABLE_BUGBEARD    //  バグベアードのOFF #endif #include "bug.h"                //  バグベアード本体の include デバッグ版 Hello, Bugbeard!(3/19) リリース版
プログラム動作ログの出力指定 #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT       //  "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br />   new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr))                                 //  標準エラーへツリー形式の出力を行うロガーの定義 #else #define BUG_DISABLE_BUGBEARD    //  バグベアードのOFF #endif #include "bug.h"                //  バグベアード本体の include デバッグ版 Hello, Bugbeard!(4/19) リリース版
デバッグ版 リリース版 Hello, Bugbeard!(5/19) ツリー形式のログ出力 #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT       //  "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br />   new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr))                                 //  標準エラーへツリー形式の出力を行うロガーの定義 #else #define BUG_DISABLE_BUGBEARD    //  バグベアードのOFF #endif #include "bug.h"                //  バグベアード本体の include 標準エラーへ出力
デバッグ版 リリース版 Hello, Bugbeard!(6/19) #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT       //  "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br />   new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr))                                 //  標準エラーへツリー形式の出力を行うロガーの定義 #else #define BUG_DISABLE_BUGBEARD    //  バグベアードのOFF #endif #include "bug.h"                //  バグベアード本体の include バグベアードを無効にする為のマクロ定義 ※ bug.hを include する前に BUG_EVIL_CONTRACT あるいは BUG_DISABLE_BUGBEARD のどちらかのマクロを定義
#if !defined(NDEBUG) #define BUG_EVIL_CONTRACT       //  "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br />   new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr))                                 //  標準エラーへツリー形式の出力を行うロガーの定義 #else #define BUG_DISABLE_BUGBEARD    //  バグベアードのOFF #endif #include "bug.h"                //  バグベアード本体の include デバッグ版 リリース版 Hello, Bugbeard!(7/19) バグベアード本体(ヘッダファイル)の include
#include <stdio.h> #include <stdlib.h> ~ここにおまじない~ int main(int argc, char * args[]) {     for(int i = 0; i < argc; ++i)     {         printf("args[%d]: %s", i, args[i]);     } BUG_puts("このロリコンどもめ!");     return EXIT_SUCCESS; } Hello, Bugbeard!(8/19) バグベアードを使った固定文字列出力
Hello, Bugbeard!(9/19) #include <stdio.h> #include <stdlib.h> ~ここにおまじない~ int main(int argc, char * args[]) {     for(int i = 0; i < argc; ++i)     {         printf("args[%d]: %s", i, args[i]);     } BUG_puts("このロリコンどもめ!");     return EXIT_SUCCESS; } ┌────────────────────────────────────── │日付&時刻:2009-12-11(金) 23:24:09.776 └─────┬──────────────────────────────── 23:24:09.776├・このロリコンどもめ! <..utorial1.cpp>#21 ┌─────┴──────────────────────────────── │日付&時刻:2009-12-11(金) 23:24:09.777 └──────────────────────────────────────
#include <stdio.h> #include <stdlib.h> ~ここにおまじない~ int main(int argc, char * args[]) {     for(int i = 0; i < argc; ++i)     {         printf("args[%d]: %s", i, args[i]);     } BUG_puts("このロリコンどもめ!");     return EXIT_SUCCESS; } Hello, Bugbeard!(10/19) プログラムの開始日時 該当行を実行した時刻 ソースファイル内の行番号 ┌────────────────────────────────────── │日付&時刻:2009-12-11(金) 23:24:09.776 └─────┬──────────────────────────────── 23:24:09.776├・このロリコンどもめ! <..utorial1.cpp>#21 ┌─────┴──────────────────────────────── │日付&時刻:2009-12-11(金) 23:24:09.777 └────────────────────────────────────── ソースファイル名 プログラムの終了日時
#include <stdio.h> #include <stdlib.h> ~ここにおまじない~ int main(int argc, char * args[]) {     for(int i = 0; i < argc; ++i)     {         printf("args[%d]: %s", i, args[i]);     } BUG_puts(BUG_FORM("argc:%d", argc));     return EXIT_SUCCESS; } Hello, Bugbeard!(11/19) バグベアードを使った書式文字列出力
#include <stdio.h> #include <stdlib.h> ~ここにおまじない~ int main(int argc, char * args[]) {     for(int i = 0; i < argc; ++i)     {         printf("args[%d]: %s", i, args[i]);     } BUG_puts(BUG_FORM("argc:%d", argc));     return EXIT_SUCCESS; } Hello, Bugbeard!(12/19) ┌────────────────────────────────────── │日付&時刻:2009-12-11(金) 23:53:50.666 └─────┬──────────────────────────────── 23:53:50.671├・argc:1 <..utorial3.cpp>#21 ┌─────┴──────────────────────────────── │日付&時刻:2009-12-11(金) 23:53:50.672 └──────────────────────────────────────
バグベアードを使った変数出力 Hello, Bugbeard!(13/19) #include <stdio.h> #include <stdlib.h> ~ここにおまじない~ int main(int argc, char * args[]) {     for(int i = 0; i < argc; ++i)     {         printf("args[%d]: %s", i, args[i]); } BUG_puts(BUG_VAL(argc)); BUG_puts(BUG_VAL(args)); BUG_puts(BUG_VAL(args[0]));     return EXIT_SUCCESS; }
Hello, Bugbeard!(14/19) #include <stdio.h> #include <stdlib.h> ~ここにおまじない~ int main(int argc, char * args[]) {     for(int i = 0; i < argc; ++i)     {         printf("args[%d]: %s", i, args[i]); } BUG_puts(BUG_VAL(argc)); BUG_puts(BUG_VAL(args)); BUG_puts(BUG_VAL(args[0]));     return EXIT_SUCCESS; } ┌────────────────────────────────────── │日付&時刻:2009-12-11(金) 23:32:38.585 └─────┬──────────────────────────────── 23:32:38.588├・argc(0x0012FF5C) = 1(0x00000001) <..utorial2.cpp>#21 23:32:38.589├・args(0x0012FF60) = HEX:D4215901 <..utorial2.cpp>#22 23:32:38.590├・args[0](0x015921D4) = “…orkutorial2.exe" <..utorial2.cpp>#23 ┌─────┴──────────────────────────────── │日付&時刻:2009-12-11(金) 23:32:38.592 └──────────────────────────────────────
Hello, Bugbeard!(15/19) 変数の値(16進数) 変数の値(10進数) 変数名 #include <stdio.h> #include <stdlib.h> ~ここにおまじない~ int main(int argc, char * args[]) {     for(int i = 0; i < argc; ++i)     {         printf("args[%d]: %s", i, args[i]); } BUG_puts(BUG_VAL(argc)); BUG_puts(BUG_VAL(args)); BUG_puts(BUG_VAL(args[0]));     return EXIT_SUCCESS; } ┌────────────────────────────────────── │日付&時刻:2009-12-11(金) 23:32:38.585 └─────┬──────────────────────────────── 23:32:38.588├・argc(0x0012FF5C) = 1(0x00000001) <..utorial2.cpp>#21 23:32:38.589├・args(0x0012FF60) = HEX:D4215901 <..utorial2.cpp>#22 23:32:38.590├・args[0](0x015921D4) = “…orkutorial2.exe" <..utorial2.cpp>#23 ┌─────┴──────────────────────────────── │日付&時刻:2009-12-11(金) 23:32:38.592 └────────────────────────────────────── 変数の値が格納されているアドレス 変数の値(文字列) 変数の値(HEX)
Hello, Bugbeard!(16/19) ステートメントハック #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT       //  "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br />   new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr))                                 //  標準エラーへツリー形式の出力を行うロガーの定義 #define BUG_STATEMENT_HACK      //  ステートメントハックの設定 #else #define BUG_DISABLE_BUGBEARD    //  バグベアードのOFF #endif #include "bug.h"                //  バグベアード本体の include
#if !defined(NDEBUG) #define BUG_EVIL_CONTRACT       //  "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br />   new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr))                                 //  標準エラーへツリー形式の出力を行うロガーの定義 #define BUG_STATEMENT_HACK      //  ステートメントハックの設定 #else #define BUG_DISABLE_BUGBEARD    //  バグベアードのOFF #endif #include "bug.h"                //  バグベアード本体の include Hello, Bugbeard!(17/19) ┌────────────────────────────────────── │日付&時刻:2008-02-24(日) 23:26:11.874 └─────┬──────────────────────────────── 23:26:11.874├┬▽if (1 < current) == true; <tree.cpp>#104 23:26:11.874│├・while (1 < current) == true; <tree.cpp>#109 23:26:11.874│├┬▽if (current %p) == true; <tree.cpp>#111 23:26:11.874││├┬▽if (pn) == false; <tree.cpp>#113 23:26:11.874│││└△if (pn) == false; <tree.cpp>#113 23:26:11.874││├・p(0x00D8FC5C) = 3(0x00000003) <tree.cpp>#126 23:26:11.874││└△if (current %p) == true; <tree.cpp>#111 23:26:11.874│├・while (1 < current) == true; <tree.cpp>#109 23:26:11.874│├┬▽if (current %p) == true; <tree.cpp>#111 23:26:11.874││├┬▽if (pn) == false; <tree.cpp>#113 23:26:11.874│││└△if (pn) == false; <tree.cpp>#113 23:26:11.874││├・p(0x00D8FC5C) = 5(0x00000005) <tree.cpp>#126 23:26:11.874││└△if (current %p) == true; <tree.cpp>#111 23:26:11.874│├・while (1 < current) == true; <tree.cpp>#109 23:26:11.874│├┬▽if (current %p) == true; <tree.cpp>#111 23:26:11.874││├┬▽if (pn) == false; <tree.cpp>#113 23:26:11.874│││└△if (pn) == false; <tree.cpp>#113
#if !defined(NDEBUG) #define BUG_EVIL_CONTRACT       //  "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br />   new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr))                                 //  標準エラーへツリー形式の出力を行うロガーの定義 #define BUG_STATEMENT_HACK      //  ステートメントハックの設定 #else #define BUG_DISABLE_BUGBEARD    //  バグベアードのOFF #endif #include "bug.h"                //  バグベアード本体の include Hello, Bugbeard!(18/19) If/while/switch 条件式の評価結果も出力 各種ステートメントのログを自動的に出力 ┌────────────────────────────────────── │日付&時刻:2008-02-24(日) 23:26:11.874 └─────┬──────────────────────────────── 23:26:11.874├┬▽if (1 < current) == true; <tree.cpp>#104 23:26:11.874│├・while (1 < current) == true; <tree.cpp>#109 23:26:11.874│├┬▽if (current %p) == true; <tree.cpp>#111 23:26:11.874││├┬▽if (pn) == false; <tree.cpp>#113 23:26:11.874│││└△if (pn) == false; <tree.cpp>#113 23:26:11.874││├・p(0x00D8FC5C) = 3(0x00000003) <tree.cpp>#126 23:26:11.874││└△if (current %p) == true; <tree.cpp>#111 23:26:11.874│├・while (1 < current) == true; <tree.cpp>#109 23:26:11.874│├┬▽if (current %p) == true; <tree.cpp>#111 23:26:11.874││├┬▽if (pn) == false; <tree.cpp>#113 23:26:11.874│││└△if (pn) == false; <tree.cpp>#113 23:26:11.874││├・p(0x00D8FC5C) = 5(0x00000005) <tree.cpp>#126 23:26:11.874││└△if (current %p) == true; <tree.cpp>#111 23:26:11.874│├・while (1 < current) == true; <tree.cpp>#109 23:26:11.874│├┬▽if (current %p) == true; <tree.cpp>#111 23:26:11.874││├┬▽if (pn) == false; <tree.cpp>#113 23:26:11.874│││└△if (pn) == false; <tree.cpp>#113 自動的に階層化して出力 詳細についてはこちらを参照のこと  http://tricklib.com/cxx/ex/bugbeard/#statements
Hello, Bugbeard!(19/19) Windows用情報収集サンプル http://tricklib.com/cxx/ex/bugbeard/#step2 Windowsで次のような情報を収集する為の関数群が用意されています Windowsバージョン情報 プロセスのEXE+全DLLのバージョン情報+ハッシュ値 メモリ情報 全ドライブの各種情報 etc Windows以外の環境でも次のような情報を収集する為の関数群が用意されています コンパイラ情報 コマンドライン引数
既存のコードへの適用 バグベアード入門
既存のコードへの適用(1/4) ステートメントハックの為のソースコードの修正 ステート内での変数定義の禁止 例外仕様構文の禁止 if (int i = …) … switch(int i = …) … while(int i = …) … この形での変数定義は禁止 ※ただし for 文についてはこの制限はありません void func(…) throw(…); 例外仕様構文は使えません
既存のコードへの適用(2/4) 特定ブロックでのステートメントハックのオフ ステートメントハックを使用する為の制限を受け入れがたい場所やどうしてもコンパイラ内部エラーが発生する箇所だけステートメントハックをオフにすることができます
既存のコードへの適用(3/4) BUG_STATEMENT_HACK を #undefして bug.hを再 #include #define BUG_STATEMENT_HACK      //  ステートメントハックの設定 #include "bug.h"                //  バグベアード本体の include #undefBUG_STATEMENT_HACK       //  ステートメントハックの設定を解除 #include "bug.h"                //  バグベアード本体の再include #define BUG_STATEMENT_HACK      //  ステートメントハックの再設定 #include "bug.h"                //  バグベアード本体の再include ステートメントハックが有効な箇所 ステートメントハックが無効な箇所 ステートメントハックが有効な箇所 BUG_STATEMENT_HACK を再度 #define して bug.hを再 #include
既存のコードへの適用(4/4) マルチスレッドなプログラムへの適用 http://tricklib.com/cxx/ex/bugbeard/#step3 #define BUG_MULTI_THREAD の指定 共用ライターの定義と各スレッド別にロガーを定義 後述のプロファイラについても各スレッド別に定義
プロファイリング バグベアード入門
プロファイリング情報の出力指定 ※カバレッジ測定が不要な場合はその出力先ライターを省略可能 プロファイリング(1/4) #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT       //  "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br />   new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr))                                 //  標準エラーへツリー形式の出力を行うロガーの定義 #define BUG_DEFINE_GLOBAL_PROFILER br />   new bugbeard::bug_tsv_profiler( br />     new bugbeard::bug_file_writer("profile.tsv"), br />     new bugbeard::bug_file_writer("coverage.tsv"))                                 //  "profile.tsv" へプロファイル結果の出力を、 //  "coverage.tsv" へカバレッジ測定結果の出力を                                //  行うプロファイルロガーの定義 #else #define BUG_DISABLE_BUGBEARD    //  バグベアードのOFF #endif #include "bug.h"                //  バグベアード本体の include デバッグ版 リリース版 プロファイラの設定
プロファイリング情報の出力指定 プロファイリング(2/4) #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT       //  "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br />   new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr))                                 //  標準エラーへツリー形式の出力を行うロガーの定義 #define BUG_DEFINE_GLOBAL_PROFILER br />   new bugbeard::bug_tsv_profiler( br />     new bugbeard::bug_file_writer("profile.tsv"), br />     new bugbeard::bug_file_writer("coverage.tsv"))                                 //  "profile.tsv" へプロファイル結果の出力を、 //  "coverage.tsv" へカバレッジ測定結果の出力を                                //  行うプロファイルロガーの定義 #else #define BUG_DISABLE_BUGBEARD    //  バグベアードのOFF #endif #include "bug.h"                //  バグベアード本体の include デバッグ版 TSV形式での出力を行うプロファイラ “profile.tsv” ファイルへ出力 リリース版
プロファイリング(3/4) プロファイリング情報の出力例 各項目の説明はこちらを参照のこと http://tricklib.com/cxx/ex/bugbeard/#profile-columns
プロファイリング(4/4) プロファイリングのポイント [合計自実働時間](TotalSelfWorkTime)がより大きなスコープがパフォーマンス上のネック [最小スタンプ](MinStamp)と[最大スタンプ](MaxStamp)で示される位置の動作ログを見比べることでそのスコープがもっとも速く動作した時ともっとも遅く動作した時の挙動を比較
カバレッジ測定 バグベアード入門
カバレッジ測定結果の出力指定 ※プロファイリングのデータが不要な場合はその出力先ライターとして NULLを指定 デバッグ版 カバレッジ測定(1/3) #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT       //  "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br />   new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr))                                 //  標準エラーへツリー形式の出力を行うロガーの定義 #define BUG_DEFINE_GLOBAL_PROFILER br />   new bugbeard::bug_tsv_profiler( br />     new bugbeard::bug_file_writer("profile.tsv"), br />     new bugbeard::bug_file_writer("coverage.tsv"))                                 //  "profile.tsv" へプロファイル結果の出力を、 //  "coverage.tsv" へカバレッジ測定結果の出力を                                //  行うプロファイルロガーの定義 #else #define BUG_DISABLE_BUGBEARD    //  バグベアードのOFF #endif #include "bug.h"                //  バグベアード本体の include “coverage.tsv” ファイルへ出力 リリース版
カバレッジ測定(2/3) カバレッジ測定結果の出力例
カバレッジ測定(3/3) if 文のカバレッジのみ switch 文やその他のカバレッジについては出力されない 全く実行されなかった if 文も出力されない
“悪魔の契約” バグベアード入門
“悪魔の契約”(1/3) バグベアードは外道なテクニックを使って作成されています 注意事項を把握した上でそれを了承する意思表明として BUG_EVIL_CONTRACT マクロを定義してください
“悪魔の契約”(2/3) 注意事項 規格違反 エラー情報の侵食 構文の制限 動作不安定 出力ログの変形 順序不安定
“悪魔の契約”(3/3) 詳細は… bug.h内のコメント 「 ★バグベアードをご利用に当たっての注意事項」 http://tricklib.com/cxx/ex/bugbeard/#evil-contract
ご利用に当たってのヒント バグベアード入門
ご利用に当たってのヒント(1/2) ご利用に当たってのヒント バグがあった場所のログ出力の為の埋め込みは消さない 三項演算子のかわりに if を使用する 明記が不要な場合でも return を記述する フィルタ機能を利用する デバッグ以外での利用 Excel を *.tsvログのビューアとして使用する場合は Excel2007 以降で
ご利用に当たってのヒント(2/2) 詳細は… bug.h内のコメント 「 ☆バグベアードをご利用に当たってのヒント」 http://tricklib.com/cxx/ex/bugbeard/#hints
質疑応答 バグベアード入門
ヽ(゚∀゚)ノご静聴ありがとうございました。

More Related Content

What's hot

Perl logging
Perl loggingPerl logging
Perl loggingkeroyonn
 
JIT のコードを読んでみた
JIT のコードを読んでみたJIT のコードを読んでみた
JIT のコードを読んでみたy-uti
 
PECL を数えてみた
PECL を数えてみたPECL を数えてみた
PECL を数えてみたy-uti
 
最近の PHP の話
最近の PHP の話最近の PHP の話
最近の PHP の話y-uti
 
知って得するC#
知って得するC#知って得するC#
知って得するC#Shota Baba
 
Hacking Ctrl-C
Hacking Ctrl-CHacking Ctrl-C
Hacking Ctrl-Cuchan_nos
 
Task Spooler を試した
Task Spooler を試したTask Spooler を試した
Task Spooler を試したy-uti
 
PHP の GC の話
PHP の GC の話PHP の GC の話
PHP の GC の話y-uti
 
家に帰るまでが遠足です
家に帰るまでが遠足です家に帰るまでが遠足です
家に帰るまでが遠足ですCryolite
 
今からでも遅くないC#開発
今からでも遅くないC#開発今からでも遅くないC#開発
今からでも遅くないC#開発Kazunori Hamamoto
 
Windows で拡張モジュールをビルドしてみた
Windows で拡張モジュールをビルドしてみたWindows で拡張モジュールをビルドしてみた
Windows で拡張モジュールをビルドしてみたy-uti
 
Perl Hobby Programming - Games::BeLike::EightBIT ターミナルで8ビット風ゲームをつくろう
Perl Hobby Programming - Games::BeLike::EightBIT ターミナルで8ビット風ゲームをつくろうPerl Hobby Programming - Games::BeLike::EightBIT ターミナルで8ビット風ゲームをつくろう
Perl Hobby Programming - Games::BeLike::EightBIT ターミナルで8ビット風ゲームをつくろうkeroyonn
 
PHP AST 徹底解説
PHP AST 徹底解説PHP AST 徹底解説
PHP AST 徹底解説do_aki
 
Mvc conf session_2_shibamura
Mvc conf session_2_shibamuraMvc conf session_2_shibamura
Mvc conf session_2_shibamuraHiroshi Okunushi
 
Use JWT access-token on Grails REST API
Use JWT access-token on Grails REST APIUse JWT access-token on Grails REST API
Use JWT access-token on Grails REST APIUehara Junji
 
Programming camp Codereading
Programming camp CodereadingProgramming camp Codereading
Programming camp CodereadingHiro Yoshioka
 
JIT for PHP を試した
JIT for PHP を試したJIT for PHP を試した
JIT for PHP を試したy-uti
 
Hack/HHVM 入門
Hack/HHVM 入門Hack/HHVM 入門
Hack/HHVM 入門y-uti
 

What's hot (20)

Perl logging
Perl loggingPerl logging
Perl logging
 
JIT のコードを読んでみた
JIT のコードを読んでみたJIT のコードを読んでみた
JIT のコードを読んでみた
 
PECL を数えてみた
PECL を数えてみたPECL を数えてみた
PECL を数えてみた
 
最近の PHP の話
最近の PHP の話最近の PHP の話
最近の PHP の話
 
知って得するC#
知って得するC#知って得するC#
知って得するC#
 
Hacking Ctrl-C
Hacking Ctrl-CHacking Ctrl-C
Hacking Ctrl-C
 
ZynqMPのQEMU
ZynqMPのQEMUZynqMPのQEMU
ZynqMPのQEMU
 
Task Spooler を試した
Task Spooler を試したTask Spooler を試した
Task Spooler を試した
 
PHP の GC の話
PHP の GC の話PHP の GC の話
PHP の GC の話
 
家に帰るまでが遠足です
家に帰るまでが遠足です家に帰るまでが遠足です
家に帰るまでが遠足です
 
今からでも遅くないC#開発
今からでも遅くないC#開発今からでも遅くないC#開発
今からでも遅くないC#開発
 
Windows で拡張モジュールをビルドしてみた
Windows で拡張モジュールをビルドしてみたWindows で拡張モジュールをビルドしてみた
Windows で拡張モジュールをビルドしてみた
 
Perl Hobby Programming - Games::BeLike::EightBIT ターミナルで8ビット風ゲームをつくろう
Perl Hobby Programming - Games::BeLike::EightBIT ターミナルで8ビット風ゲームをつくろうPerl Hobby Programming - Games::BeLike::EightBIT ターミナルで8ビット風ゲームをつくろう
Perl Hobby Programming - Games::BeLike::EightBIT ターミナルで8ビット風ゲームをつくろう
 
PHP AST 徹底解説
PHP AST 徹底解説PHP AST 徹底解説
PHP AST 徹底解説
 
Mvc conf session_2_shibamura
Mvc conf session_2_shibamuraMvc conf session_2_shibamura
Mvc conf session_2_shibamura
 
Use JWT access-token on Grails REST API
Use JWT access-token on Grails REST APIUse JWT access-token on Grails REST API
Use JWT access-token on Grails REST API
 
Programming camp Codereading
Programming camp CodereadingProgramming camp Codereading
Programming camp Codereading
 
JIT for PHP を試した
JIT for PHP を試したJIT for PHP を試した
JIT for PHP を試した
 
Hack/HHVM 入門
Hack/HHVM 入門Hack/HHVM 入門
Hack/HHVM 入門
 
PHPコアから読み解くPHP5.5
PHPコアから読み解くPHP5.5PHPコアから読み解くPHP5.5
PHPコアから読み解くPHP5.5
 

Similar to バグベアード入門

JavaScript And Debug
JavaScript And DebugJavaScript And Debug
JavaScript And Debuguupaa
 
GNU awk (gawk) を用いた Apache ログ解析方法
GNU awk (gawk) を用いた Apache ログ解析方法GNU awk (gawk) を用いた Apache ログ解析方法
GNU awk (gawk) を用いた Apache ログ解析方法博文 斉藤
 
Python東海GAEやってみた
Python東海GAEやってみたPython東海GAEやってみた
Python東海GAEやってみたMori Shingo
 
Groovy Bootcamp 2015 by JGGUG
Groovy Bootcamp 2015 by JGGUGGroovy Bootcamp 2015 by JGGUG
Groovy Bootcamp 2015 by JGGUGUehara Junji
 
groovy 2.1.0 20130118
groovy 2.1.0 20130118groovy 2.1.0 20130118
groovy 2.1.0 20130118Uehara Junji
 
Debug Hacks at Security and Programming camp 2011
Debug Hacks at Security and Programming camp 2011 Debug Hacks at Security and Programming camp 2011
Debug Hacks at Security and Programming camp 2011 Hiro Yoshioka
 
プログラミングで言いたい聞きたいこと集
プログラミングで言いたい聞きたいこと集プログラミングで言いたい聞きたいこと集
プログラミングで言いたい聞きたいこと集tecopark
 
プログラミングで言いたいこと聞きたいこと集
プログラミングで言いたいこと聞きたいこと集プログラミングで言いたいこと聞きたいこと集
プログラミングで言いたいこと聞きたいこと集tecopark
 
Groovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみようGroovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみようAkira Shimosako
 
Programming camp 2010 debug hacks
Programming camp 2010 debug hacksProgramming camp 2010 debug hacks
Programming camp 2010 debug hacksHiro Yoshioka
 
Ansible 2.8 アップデート情報 -機能追加と注意点-
Ansible 2.8 アップデート情報 -機能追加と注意点-Ansible 2.8 アップデート情報 -機能追加と注意点-
Ansible 2.8 アップデート情報 -機能追加と注意点-akira6592
 
bc10 (Android 2.2対応) について @Gadget1 R2
bc10 (Android 2.2対応) について @Gadget1 R2 bc10 (Android 2.2対応) について @Gadget1 R2
bc10 (Android 2.2対応) について @Gadget1 R2 BeatCraft
 
アプリコンテスト
アプリコンテストアプリコンテスト
アプリコンテストTomonori Yamada
 
こんにちはGroovy
こんにちはGroovyこんにちはGroovy
こんにちはGroovyirof N
 
Hacking Ruby with Python
Hacking Ruby with PythonHacking Ruby with Python
Hacking Ruby with PythonTaisuke Yamada
 
つ部 Android Studio 勉強会 12/7
つ部 Android Studio 勉強会 12/7つ部 Android Studio 勉強会 12/7
つ部 Android Studio 勉強会 12/7Hikaru Wada
 
Zend Frameworkで始める携帯サイト
Zend Frameworkで始める携帯サイトZend Frameworkで始める携帯サイト
Zend Frameworkで始める携帯サイト清水樹
 
TypeScript と Visual Studio Code
TypeScript と Visual Studio CodeTypeScript と Visual Studio Code
TypeScript と Visual Studio CodeAkira Inoue
 
UniRx - Reactive Extensions for Unity
UniRx - Reactive Extensions for UnityUniRx - Reactive Extensions for Unity
UniRx - Reactive Extensions for UnityYoshifumi Kawai
 

Similar to バグベアード入門 (20)

JavaScript And Debug
JavaScript And DebugJavaScript And Debug
JavaScript And Debug
 
GNU awk (gawk) を用いた Apache ログ解析方法
GNU awk (gawk) を用いた Apache ログ解析方法GNU awk (gawk) を用いた Apache ログ解析方法
GNU awk (gawk) を用いた Apache ログ解析方法
 
Python東海GAEやってみた
Python東海GAEやってみたPython東海GAEやってみた
Python東海GAEやってみた
 
Groovy Bootcamp 2015 by JGGUG
Groovy Bootcamp 2015 by JGGUGGroovy Bootcamp 2015 by JGGUG
Groovy Bootcamp 2015 by JGGUG
 
groovy 2.1.0 20130118
groovy 2.1.0 20130118groovy 2.1.0 20130118
groovy 2.1.0 20130118
 
Debug Hacks at Security and Programming camp 2011
Debug Hacks at Security and Programming camp 2011 Debug Hacks at Security and Programming camp 2011
Debug Hacks at Security and Programming camp 2011
 
プログラミングで言いたい聞きたいこと集
プログラミングで言いたい聞きたいこと集プログラミングで言いたい聞きたいこと集
プログラミングで言いたい聞きたいこと集
 
プログラミングで言いたいこと聞きたいこと集
プログラミングで言いたいこと聞きたいこと集プログラミングで言いたいこと聞きたいこと集
プログラミングで言いたいこと聞きたいこと集
 
Groovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみようGroovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみよう
 
Programming camp 2010 debug hacks
Programming camp 2010 debug hacksProgramming camp 2010 debug hacks
Programming camp 2010 debug hacks
 
Ansible 2.8 アップデート情報 -機能追加と注意点-
Ansible 2.8 アップデート情報 -機能追加と注意点-Ansible 2.8 アップデート情報 -機能追加と注意点-
Ansible 2.8 アップデート情報 -機能追加と注意点-
 
bc10 (Android 2.2対応) について @Gadget1 R2
bc10 (Android 2.2対応) について @Gadget1 R2 bc10 (Android 2.2対応) について @Gadget1 R2
bc10 (Android 2.2対応) について @Gadget1 R2
 
アプリコンテスト
アプリコンテストアプリコンテスト
アプリコンテスト
 
こんにちはGroovy
こんにちはGroovyこんにちはGroovy
こんにちはGroovy
 
Hacking Ruby with Python
Hacking Ruby with PythonHacking Ruby with Python
Hacking Ruby with Python
 
つ部 Android Studio 勉強会 12/7
つ部 Android Studio 勉強会 12/7つ部 Android Studio 勉強会 12/7
つ部 Android Studio 勉強会 12/7
 
TextMate
TextMateTextMate
TextMate
 
Zend Frameworkで始める携帯サイト
Zend Frameworkで始める携帯サイトZend Frameworkで始める携帯サイト
Zend Frameworkで始める携帯サイト
 
TypeScript と Visual Studio Code
TypeScript と Visual Studio CodeTypeScript と Visual Studio Code
TypeScript と Visual Studio Code
 
UniRx - Reactive Extensions for Unity
UniRx - Reactive Extensions for UnityUniRx - Reactive Extensions for Unity
UniRx - Reactive Extensions for Unity
 

More from 道化師 堂華

Reflection with xamarin.forms
Reflection with xamarin.formsReflection with xamarin.forms
Reflection with xamarin.forms道化師 堂華
 
独りガラパゴス開発
独りガラパゴス開発独りガラパゴス開発
独りガラパゴス開発道化師 堂華
 
C++ tips 3 カンマ演算子編
C++ tips 3 カンマ演算子編C++ tips 3 カンマ演算子編
C++ tips 3 カンマ演算子編道化師 堂華
 
C++ tips2 インクリメント編
C++ tips2 インクリメント編C++ tips2 インクリメント編
C++ tips2 インクリメント編道化師 堂華
 
エラーハンドリングモデル考察
エラーハンドリングモデル考察エラーハンドリングモデル考察
エラーハンドリングモデル考察道化師 堂華
 
C++プログラマの為のセキュリティ入門
C++プログラマの為のセキュリティ入門C++プログラマの為のセキュリティ入門
C++プログラマの為のセキュリティ入門道化師 堂華
 
エラーハンドリング
エラーハンドリングエラーハンドリング
エラーハンドリング道化師 堂華
 
マスタリング バベル
マスタリング バベルマスタリング バベル
マスタリング バベル道化師 堂華
 
並列プログラミング 入門!&おさらい!
並列プログラミング入門!&おさらい!並列プログラミング入門!&おさらい!
並列プログラミング 入門!&おさらい!道化師 堂華
 
LUCIFERの設計コンセプトと 導入予定の機能紹介
LUCIFERの設計コンセプトと 導入予定の機能紹介LUCIFERの設計コンセプトと 導入予定の機能紹介
LUCIFERの設計コンセプトと 導入予定の機能紹介道化師 堂華
 

More from 道化師 堂華 (13)

Reflection with xamarin.forms
Reflection with xamarin.formsReflection with xamarin.forms
Reflection with xamarin.forms
 
独りガラパゴス開発
独りガラパゴス開発独りガラパゴス開発
独りガラパゴス開発
 
C++ tips4 cv修飾編
C++ tips4 cv修飾編C++ tips4 cv修飾編
C++ tips4 cv修飾編
 
C++ tips 3 カンマ演算子編
C++ tips 3 カンマ演算子編C++ tips 3 カンマ演算子編
C++ tips 3 カンマ演算子編
 
C++ tips2 インクリメント編
C++ tips2 インクリメント編C++ tips2 インクリメント編
C++ tips2 インクリメント編
 
C++ tips1 #include編
C++ tips1 #include編C++ tips1 #include編
C++ tips1 #include編
 
エラーハンドリングモデル考察
エラーハンドリングモデル考察エラーハンドリングモデル考察
エラーハンドリングモデル考察
 
C++0x総復習
C++0x総復習C++0x総復習
C++0x総復習
 
C++プログラマの為のセキュリティ入門
C++プログラマの為のセキュリティ入門C++プログラマの為のセキュリティ入門
C++プログラマの為のセキュリティ入門
 
エラーハンドリング
エラーハンドリングエラーハンドリング
エラーハンドリング
 
マスタリング バベル
マスタリング バベルマスタリング バベル
マスタリング バベル
 
並列プログラミング 入門!&おさらい!
並列プログラミング入門!&おさらい!並列プログラミング入門!&おさらい!
並列プログラミング 入門!&おさらい!
 
LUCIFERの設計コンセプトと 導入予定の機能紹介
LUCIFERの設計コンセプトと 導入予定の機能紹介LUCIFERの設計コンセプトと 導入予定の機能紹介
LUCIFERの設計コンセプトと 導入予定の機能紹介
 

Recently uploaded

業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NTT DATA Technology & Innovation
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 

Recently uploaded (8)

業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 

バグベアード入門

  • 3. 概要 バグベアードとは? Hello, Bugbeard! 既存のコードへの適用 プロファイリング カバレッジ測定 “悪魔の契約” ご利用に当たってのヒント
  • 5. バグベアードとは?(1/5) Boost C++ Libraries とは関係ありません。 Boost 採用に向けて協力してくださる方がいれば検討します。 私の英語力が頼りないので、主にコミュニケーションのサポートをして頂ければ…
  • 6. バグベアードとは?(2/5) printf デバッギングを簡単且つゴージャスに行う為のヘッダーファイル サンプルおよびドキュメント関係やおまけのアイコンファイルを除けばバグベアードは bug.hだけで、他にはなにもありません 若干のマクロによる指定とともにインクルードするだけ
  • 8. バグベアードとは?(4/5) etc ライセンスフリー マルチプロセス/マルチスレッド対応 各種ログの出力先、出力形式を自在にカスタマイズ可能 Windows と POSIX な環境に対応 その他の環境(カーネルモード含む)も要望があれば対応を検討します ANSI(MBCS)/Unicode に対応 日本語/英語を切り替え可能 ソースコードレベルで組み込まれるのでユーザー環境でも特殊なツールをインストールしたりすることなくそのまま使用可能
  • 11. Hello, Bugbeard!(1/19) まずは bug.hをダウンロード http://tricklib.com/cxx/ex/bugbeard/bug.h
  • 12. Hello, Bugbeard!(2/19) ソースコードにおまじないを記述 #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT // "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br /> new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr)) // 標準エラーへツリー形式の出力を行うロガーの定義 #else #define BUG_DISABLE_BUGBEARD // バグベアードのOFF #endif #include "bug.h" // バグベアード本体の include
  • 13. バグベアードを有効にする為のマクロ定義 (※後半の”悪魔の契約”にて説明) #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT // "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br /> new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr)) // 標準エラーへツリー形式の出力を行うロガーの定義 #else #define BUG_DISABLE_BUGBEARD // バグベアードのOFF #endif #include "bug.h" // バグベアード本体の include デバッグ版 Hello, Bugbeard!(3/19) リリース版
  • 14. プログラム動作ログの出力指定 #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT // "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br /> new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr)) // 標準エラーへツリー形式の出力を行うロガーの定義 #else #define BUG_DISABLE_BUGBEARD // バグベアードのOFF #endif #include "bug.h" // バグベアード本体の include デバッグ版 Hello, Bugbeard!(4/19) リリース版
  • 15. デバッグ版 リリース版 Hello, Bugbeard!(5/19) ツリー形式のログ出力 #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT // "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br /> new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr)) // 標準エラーへツリー形式の出力を行うロガーの定義 #else #define BUG_DISABLE_BUGBEARD // バグベアードのOFF #endif #include "bug.h" // バグベアード本体の include 標準エラーへ出力
  • 16. デバッグ版 リリース版 Hello, Bugbeard!(6/19) #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT // "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br /> new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr)) // 標準エラーへツリー形式の出力を行うロガーの定義 #else #define BUG_DISABLE_BUGBEARD // バグベアードのOFF #endif #include "bug.h" // バグベアード本体の include バグベアードを無効にする為のマクロ定義 ※ bug.hを include する前に BUG_EVIL_CONTRACT あるいは BUG_DISABLE_BUGBEARD のどちらかのマクロを定義
  • 17. #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT // "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br /> new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr)) // 標準エラーへツリー形式の出力を行うロガーの定義 #else #define BUG_DISABLE_BUGBEARD // バグベアードのOFF #endif #include "bug.h" // バグベアード本体の include デバッグ版 リリース版 Hello, Bugbeard!(7/19) バグベアード本体(ヘッダファイル)の include
  • 18. #include <stdio.h> #include <stdlib.h> ~ここにおまじない~ int main(int argc, char * args[]) { for(int i = 0; i < argc; ++i) { printf("args[%d]: %s", i, args[i]); } BUG_puts("このロリコンどもめ!"); return EXIT_SUCCESS; } Hello, Bugbeard!(8/19) バグベアードを使った固定文字列出力
  • 19. Hello, Bugbeard!(9/19) #include <stdio.h> #include <stdlib.h> ~ここにおまじない~ int main(int argc, char * args[]) { for(int i = 0; i < argc; ++i) { printf("args[%d]: %s", i, args[i]); } BUG_puts("このロリコンどもめ!"); return EXIT_SUCCESS; } ┌────────────────────────────────────── │日付&時刻:2009-12-11(金) 23:24:09.776 └─────┬──────────────────────────────── 23:24:09.776├・このロリコンどもめ! <..utorial1.cpp>#21 ┌─────┴──────────────────────────────── │日付&時刻:2009-12-11(金) 23:24:09.777 └──────────────────────────────────────
  • 20. #include <stdio.h> #include <stdlib.h> ~ここにおまじない~ int main(int argc, char * args[]) { for(int i = 0; i < argc; ++i) { printf("args[%d]: %s", i, args[i]); } BUG_puts("このロリコンどもめ!"); return EXIT_SUCCESS; } Hello, Bugbeard!(10/19) プログラムの開始日時 該当行を実行した時刻 ソースファイル内の行番号 ┌────────────────────────────────────── │日付&時刻:2009-12-11(金) 23:24:09.776 └─────┬──────────────────────────────── 23:24:09.776├・このロリコンどもめ! <..utorial1.cpp>#21 ┌─────┴──────────────────────────────── │日付&時刻:2009-12-11(金) 23:24:09.777 └────────────────────────────────────── ソースファイル名 プログラムの終了日時
  • 21. #include <stdio.h> #include <stdlib.h> ~ここにおまじない~ int main(int argc, char * args[]) { for(int i = 0; i < argc; ++i) { printf("args[%d]: %s", i, args[i]); } BUG_puts(BUG_FORM("argc:%d", argc)); return EXIT_SUCCESS; } Hello, Bugbeard!(11/19) バグベアードを使った書式文字列出力
  • 22. #include <stdio.h> #include <stdlib.h> ~ここにおまじない~ int main(int argc, char * args[]) { for(int i = 0; i < argc; ++i) { printf("args[%d]: %s", i, args[i]); } BUG_puts(BUG_FORM("argc:%d", argc)); return EXIT_SUCCESS; } Hello, Bugbeard!(12/19) ┌────────────────────────────────────── │日付&時刻:2009-12-11(金) 23:53:50.666 └─────┬──────────────────────────────── 23:53:50.671├・argc:1 <..utorial3.cpp>#21 ┌─────┴──────────────────────────────── │日付&時刻:2009-12-11(金) 23:53:50.672 └──────────────────────────────────────
  • 23. バグベアードを使った変数出力 Hello, Bugbeard!(13/19) #include <stdio.h> #include <stdlib.h> ~ここにおまじない~ int main(int argc, char * args[]) { for(int i = 0; i < argc; ++i) { printf("args[%d]: %s", i, args[i]); } BUG_puts(BUG_VAL(argc)); BUG_puts(BUG_VAL(args)); BUG_puts(BUG_VAL(args[0])); return EXIT_SUCCESS; }
  • 24. Hello, Bugbeard!(14/19) #include <stdio.h> #include <stdlib.h> ~ここにおまじない~ int main(int argc, char * args[]) { for(int i = 0; i < argc; ++i) { printf("args[%d]: %s", i, args[i]); } BUG_puts(BUG_VAL(argc)); BUG_puts(BUG_VAL(args)); BUG_puts(BUG_VAL(args[0])); return EXIT_SUCCESS; } ┌────────────────────────────────────── │日付&時刻:2009-12-11(金) 23:32:38.585 └─────┬──────────────────────────────── 23:32:38.588├・argc(0x0012FF5C) = 1(0x00000001) <..utorial2.cpp>#21 23:32:38.589├・args(0x0012FF60) = HEX:D4215901 <..utorial2.cpp>#22 23:32:38.590├・args[0](0x015921D4) = “…orkutorial2.exe" <..utorial2.cpp>#23 ┌─────┴──────────────────────────────── │日付&時刻:2009-12-11(金) 23:32:38.592 └──────────────────────────────────────
  • 25. Hello, Bugbeard!(15/19) 変数の値(16進数) 変数の値(10進数) 変数名 #include <stdio.h> #include <stdlib.h> ~ここにおまじない~ int main(int argc, char * args[]) { for(int i = 0; i < argc; ++i) { printf("args[%d]: %s", i, args[i]); } BUG_puts(BUG_VAL(argc)); BUG_puts(BUG_VAL(args)); BUG_puts(BUG_VAL(args[0])); return EXIT_SUCCESS; } ┌────────────────────────────────────── │日付&時刻:2009-12-11(金) 23:32:38.585 └─────┬──────────────────────────────── 23:32:38.588├・argc(0x0012FF5C) = 1(0x00000001) <..utorial2.cpp>#21 23:32:38.589├・args(0x0012FF60) = HEX:D4215901 <..utorial2.cpp>#22 23:32:38.590├・args[0](0x015921D4) = “…orkutorial2.exe" <..utorial2.cpp>#23 ┌─────┴──────────────────────────────── │日付&時刻:2009-12-11(金) 23:32:38.592 └────────────────────────────────────── 変数の値が格納されているアドレス 変数の値(文字列) 変数の値(HEX)
  • 26. Hello, Bugbeard!(16/19) ステートメントハック #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT // "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br /> new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr)) // 標準エラーへツリー形式の出力を行うロガーの定義 #define BUG_STATEMENT_HACK // ステートメントハックの設定 #else #define BUG_DISABLE_BUGBEARD // バグベアードのOFF #endif #include "bug.h" // バグベアード本体の include
  • 27. #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT // "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br /> new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr)) // 標準エラーへツリー形式の出力を行うロガーの定義 #define BUG_STATEMENT_HACK // ステートメントハックの設定 #else #define BUG_DISABLE_BUGBEARD // バグベアードのOFF #endif #include "bug.h" // バグベアード本体の include Hello, Bugbeard!(17/19) ┌────────────────────────────────────── │日付&時刻:2008-02-24(日) 23:26:11.874 └─────┬──────────────────────────────── 23:26:11.874├┬▽if (1 < current) == true; <tree.cpp>#104 23:26:11.874│├・while (1 < current) == true; <tree.cpp>#109 23:26:11.874│├┬▽if (current %p) == true; <tree.cpp>#111 23:26:11.874││├┬▽if (pn) == false; <tree.cpp>#113 23:26:11.874│││└△if (pn) == false; <tree.cpp>#113 23:26:11.874││├・p(0x00D8FC5C) = 3(0x00000003) <tree.cpp>#126 23:26:11.874││└△if (current %p) == true; <tree.cpp>#111 23:26:11.874│├・while (1 < current) == true; <tree.cpp>#109 23:26:11.874│├┬▽if (current %p) == true; <tree.cpp>#111 23:26:11.874││├┬▽if (pn) == false; <tree.cpp>#113 23:26:11.874│││└△if (pn) == false; <tree.cpp>#113 23:26:11.874││├・p(0x00D8FC5C) = 5(0x00000005) <tree.cpp>#126 23:26:11.874││└△if (current %p) == true; <tree.cpp>#111 23:26:11.874│├・while (1 < current) == true; <tree.cpp>#109 23:26:11.874│├┬▽if (current %p) == true; <tree.cpp>#111 23:26:11.874││├┬▽if (pn) == false; <tree.cpp>#113 23:26:11.874│││└△if (pn) == false; <tree.cpp>#113
  • 28. #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT // "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br /> new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr)) // 標準エラーへツリー形式の出力を行うロガーの定義 #define BUG_STATEMENT_HACK // ステートメントハックの設定 #else #define BUG_DISABLE_BUGBEARD // バグベアードのOFF #endif #include "bug.h" // バグベアード本体の include Hello, Bugbeard!(18/19) If/while/switch 条件式の評価結果も出力 各種ステートメントのログを自動的に出力 ┌────────────────────────────────────── │日付&時刻:2008-02-24(日) 23:26:11.874 └─────┬──────────────────────────────── 23:26:11.874├┬▽if (1 < current) == true; <tree.cpp>#104 23:26:11.874│├・while (1 < current) == true; <tree.cpp>#109 23:26:11.874│├┬▽if (current %p) == true; <tree.cpp>#111 23:26:11.874││├┬▽if (pn) == false; <tree.cpp>#113 23:26:11.874│││└△if (pn) == false; <tree.cpp>#113 23:26:11.874││├・p(0x00D8FC5C) = 3(0x00000003) <tree.cpp>#126 23:26:11.874││└△if (current %p) == true; <tree.cpp>#111 23:26:11.874│├・while (1 < current) == true; <tree.cpp>#109 23:26:11.874│├┬▽if (current %p) == true; <tree.cpp>#111 23:26:11.874││├┬▽if (pn) == false; <tree.cpp>#113 23:26:11.874│││└△if (pn) == false; <tree.cpp>#113 23:26:11.874││├・p(0x00D8FC5C) = 5(0x00000005) <tree.cpp>#126 23:26:11.874││└△if (current %p) == true; <tree.cpp>#111 23:26:11.874│├・while (1 < current) == true; <tree.cpp>#109 23:26:11.874│├┬▽if (current %p) == true; <tree.cpp>#111 23:26:11.874││├┬▽if (pn) == false; <tree.cpp>#113 23:26:11.874│││└△if (pn) == false; <tree.cpp>#113 自動的に階層化して出力 詳細についてはこちらを参照のこと  http://tricklib.com/cxx/ex/bugbeard/#statements
  • 29. Hello, Bugbeard!(19/19) Windows用情報収集サンプル http://tricklib.com/cxx/ex/bugbeard/#step2 Windowsで次のような情報を収集する為の関数群が用意されています Windowsバージョン情報 プロセスのEXE+全DLLのバージョン情報+ハッシュ値 メモリ情報 全ドライブの各種情報 etc Windows以外の環境でも次のような情報を収集する為の関数群が用意されています コンパイラ情報 コマンドライン引数
  • 31. 既存のコードへの適用(1/4) ステートメントハックの為のソースコードの修正 ステート内での変数定義の禁止 例外仕様構文の禁止 if (int i = …) … switch(int i = …) … while(int i = …) … この形での変数定義は禁止 ※ただし for 文についてはこの制限はありません void func(…) throw(…); 例外仕様構文は使えません
  • 33. 既存のコードへの適用(3/4) BUG_STATEMENT_HACK を #undefして bug.hを再 #include #define BUG_STATEMENT_HACK // ステートメントハックの設定 #include "bug.h" // バグベアード本体の include #undefBUG_STATEMENT_HACK // ステートメントハックの設定を解除 #include "bug.h" // バグベアード本体の再include #define BUG_STATEMENT_HACK // ステートメントハックの再設定 #include "bug.h" // バグベアード本体の再include ステートメントハックが有効な箇所 ステートメントハックが無効な箇所 ステートメントハックが有効な箇所 BUG_STATEMENT_HACK を再度 #define して bug.hを再 #include
  • 34. 既存のコードへの適用(4/4) マルチスレッドなプログラムへの適用 http://tricklib.com/cxx/ex/bugbeard/#step3 #define BUG_MULTI_THREAD の指定 共用ライターの定義と各スレッド別にロガーを定義 後述のプロファイラについても各スレッド別に定義
  • 36. プロファイリング情報の出力指定 ※カバレッジ測定が不要な場合はその出力先ライターを省略可能 プロファイリング(1/4) #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT // "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br /> new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr)) // 標準エラーへツリー形式の出力を行うロガーの定義 #define BUG_DEFINE_GLOBAL_PROFILER br /> new bugbeard::bug_tsv_profiler( br /> new bugbeard::bug_file_writer("profile.tsv"), br /> new bugbeard::bug_file_writer("coverage.tsv")) // "profile.tsv" へプロファイル結果の出力を、 // "coverage.tsv" へカバレッジ測定結果の出力を // 行うプロファイルロガーの定義 #else #define BUG_DISABLE_BUGBEARD // バグベアードのOFF #endif #include "bug.h" // バグベアード本体の include デバッグ版 リリース版 プロファイラの設定
  • 37. プロファイリング情報の出力指定 プロファイリング(2/4) #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT // "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br /> new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr)) // 標準エラーへツリー形式の出力を行うロガーの定義 #define BUG_DEFINE_GLOBAL_PROFILER br /> new bugbeard::bug_tsv_profiler( br /> new bugbeard::bug_file_writer("profile.tsv"), br /> new bugbeard::bug_file_writer("coverage.tsv")) // "profile.tsv" へプロファイル結果の出力を、 // "coverage.tsv" へカバレッジ測定結果の出力を // 行うプロファイルロガーの定義 #else #define BUG_DISABLE_BUGBEARD // バグベアードのOFF #endif #include "bug.h" // バグベアード本体の include デバッグ版 TSV形式での出力を行うプロファイラ “profile.tsv” ファイルへ出力 リリース版
  • 39. プロファイリング(4/4) プロファイリングのポイント [合計自実働時間](TotalSelfWorkTime)がより大きなスコープがパフォーマンス上のネック [最小スタンプ](MinStamp)と[最大スタンプ](MaxStamp)で示される位置の動作ログを見比べることでそのスコープがもっとも速く動作した時ともっとも遅く動作した時の挙動を比較
  • 41. カバレッジ測定結果の出力指定 ※プロファイリングのデータが不要な場合はその出力先ライターとして NULLを指定 デバッグ版 カバレッジ測定(1/3) #if !defined(NDEBUG) #define BUG_EVIL_CONTRACT // "悪魔の契約" #define BUG_DEFINE_GLOBAL_LOGGER br /> new bugbeard::bug_tree_logger(new bugbeard::bug_file_writer_base(stderr)) // 標準エラーへツリー形式の出力を行うロガーの定義 #define BUG_DEFINE_GLOBAL_PROFILER br /> new bugbeard::bug_tsv_profiler( br /> new bugbeard::bug_file_writer("profile.tsv"), br /> new bugbeard::bug_file_writer("coverage.tsv")) // "profile.tsv" へプロファイル結果の出力を、 // "coverage.tsv" へカバレッジ測定結果の出力を // 行うプロファイルロガーの定義 #else #define BUG_DISABLE_BUGBEARD // バグベアードのOFF #endif #include "bug.h" // バグベアード本体の include “coverage.tsv” ファイルへ出力 リリース版
  • 43. カバレッジ測定(3/3) if 文のカバレッジのみ switch 文やその他のカバレッジについては出力されない 全く実行されなかった if 文も出力されない
  • 46. “悪魔の契約”(2/3) 注意事項 規格違反 エラー情報の侵食 構文の制限 動作不安定 出力ログの変形 順序不安定
  • 47. “悪魔の契約”(3/3) 詳細は… bug.h内のコメント 「 ★バグベアードをご利用に当たっての注意事項」 http://tricklib.com/cxx/ex/bugbeard/#evil-contract
  • 49. ご利用に当たってのヒント(1/2) ご利用に当たってのヒント バグがあった場所のログ出力の為の埋め込みは消さない 三項演算子のかわりに if を使用する 明記が不要な場合でも return を記述する フィルタ機能を利用する デバッグ以外での利用 Excel を *.tsvログのビューアとして使用する場合は Excel2007 以降で
  • 50. ご利用に当たってのヒント(2/2) 詳細は… bug.h内のコメント 「 ☆バグベアードをご利用に当たってのヒント」 http://tricklib.com/cxx/ex/bugbeard/#hints