再現しにくいバグのデバックについて
VisualStudio 6.0(EP)(SP5) VC++6.0 SQLServer7.0(SP4)
WinXp(SP1)
MFC、ODBC接続
参考サンプル VSWAP32
サンプルはそのままコンパイルすればエラーも出なく、正常に動作するものです
現状、レコードセット 8、ビュークラス 10 ドキュメント 1
で処理しています
本題なのですが
再現しにくいバグのデバックについてなのですが、自分のコーディングミスで起きてい
るのは当然なのですが
-------------------------------------------------------------------
void CMRU10_COSView::OnCosDelt()
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
}
-------------------------------------------------------------------
このように生成しただけで何も記述していない、
ビューに貼り付けたボタンに対するメッセージマップBN_CLICKEDに対する関数で、
アーサッションが起きるのです
エラー表示の時もここの情報表示だけです
リコンパイルせず、再度再現しようとしてもエラーが出てこなく
2・3日いじって、別のボタンで、突然出て再現させようとしても
再現させることができなくて困ってます
なお、自分で意識的に「ASSERT」「TRY」「CATCH」いれていません
実際どこに入れればよいかわからないのも理由のひとつですけど
今まではトレース実行だけでバグ解決できていました
こんな不安定なもの世に出せません
デバック方法に対する助言いただけませんでしょうか
よろしくお願いします
XPならではの方法もあると思うのですが、情報解析の方法が
わかりません
多少雑談になるようなものでも結構です(趣旨に沿っているものであれば)
assert文の内容が示されていないので一般的な話にしかなりませんが、assertが出ている
のなら、デバッガを使えば何というファイルの何という関数の何というassert文で引っか
かったか、位は解ると思います。その文を読めばエラーの理由はわかりますよね。そした
らコールスタックを辿っていくか、その関数に至るまでの過程をステップ実行で追ってい
くか...が常套手段だとおもいます。
あくまで私の場合はですが、大抵これで原因は突き止められるでしょう。まぁ、
>今まではトレース実行だけでバグ解決できていました
ということなので、これくらいのことは既にされているのかもしれません。
私の経験では、
・バッファーオーバーラン
・HANDLEなどのリソースの解放ミス
等で再現性のないエラーが起こることがありました。
メッセージハンドラをもつクラスのメンバ周りに
エラーの原因が隠れているかもしれません。
tibさん、ten_bun さん ご返事ありがとうございます
説明の仕方悪くてすみませんでした
アーサッション起こしてからそこですぐでバックに走らず
見逃(故意に)して再現しようとしても再現できないのです
PCの電源切っても2・3日再現できないんです
今までに数回遭遇していますが
こんな何の変哲もない関数(最初に書いてありますけど)
を示していたことだけ記憶してます
>void CMRU10_COSView::OnCosDelt()
指し示す関数名が違う時でも空記述の関数さしているんです
「アサーションが起こる」というのは
「Debug assertion failed!(failure!だったかな?)」
というメッセージとともに[中止][再試行][キャンセル]の3つのボタンの
付いたメッセージボックスが出てくる、ということではないのでしょうか?
tibさんの繰り返しになっちゃいますが、
普通は上記のようなメッセージボックスが出てきたら
[再試行]を押してアサートが失敗した行を表示させ、
必要であればコールスタックを眺めるなどしてその原因を調べると思うんですが。
そうしない、あるいはできない理由は何なのでしょう?
「バックに走らず」というのがよくわからないのですが、
なぜ見逃すのでしょうか?
> >void CMRU10_COSView::OnCosDelt()
> 指し示す関数名が違う時でも空記述の関数さしているんです
何がどこを指してるんでしょう?
#ってまさかMFCのソースをインストールしてないというオチじゃ・・・
余談になりますが、
> なお、自分で意識的に「ASSERT」「TRY」「CATCH」いれていません
ASSERTやVERIFYは入れた方がソースの可読性が上がると思いますよ。
「この時点ではこの変数はこうなっているはずだ」という表明です。
とりあえず関数の引数チェックに使用してみるのが吉かと。
好みの問題かもしれないので無理にとは言いませんが。
>>そこですぐでバックに走らず
>「バックに走らず」というのがよくわからないのですが、
「そこで、すぐ、デバッグに走らず」のスペルミス&誤変換でしょう。
>多少雑談になるようなものでも結構です
ということなので書きますが、「バグとの出会いは一期一会」。再現性の低いバグと解っ
ているならなおのこと、そのバグを見つけた瞬間に解明しようとする努力を怠ってはいけ
ないのではないでしょうか。
>「そこで、すぐ、デバッグに走らず」のスペルミス&誤変換でしょう。
ああ(笑
失礼しました。
pie さん、tibさん ありがとうございます
>>「バックに走らず」というのがよくわからないのですが、
>「そこで、すぐ、デバッグに走らず」のスペルミス&誤変換でしょう。
大当たりです、ごめんなさい
> なお、自分で意識的に「ASSERT」「TRY」「CATCH」いれていません
実は入れ方がよく分からないと言う事の方が多かったりして
はじめて使ったのは「CDBException」でした、ハンドルについては
何を使うのがよいのか分かっていません、どこに入れればよいのか
>[再試行]を押してアサートが失敗した行を表示させ、
>必要であればコールスタックを眺めるなどしてその原因を調べると思うんですが。
>そうしない、あるいはできない理由は何なのでしょう?
特に理由と言うのは無いです、アサートが失敗した時に
「xxxx.cppのAAA::BBBにあります」とか出ますよね
このBBBの中身のコーディングしていない心当たりがあって
そのまま「中止」にしちゃうこと、多いんです
中身「コーディング」すると、出なくなっちゃうんです
再現させようと、コーディングした所を 「/* ~~~~ */」のように
囲んでコンパイルしたりしているのですけど、再現できなく成るんです
参考紹介ですけど(完全余談かな?)
「秀和 システム Visual C++ 逆引き大全 500の極意」や
「inside Visual C++ 4.0/5.0」などが今のところ
メインの参考書になってますけど
「MSDN ライブラリ 2001 年 10 月リリース」を見ている事多くなってきました
と言うより、なんとなく、見なれてきました、ここの質問で自分にまったく関係ない
質問の意味探したり、している内にチョットずつ探せるように成ってきました
これもひとえに私の暴言に付き合っていただいている皆様のおかげです
ここで「感謝・感謝」
>そのまま「中止」にしちゃうこと、多いんです
これがそもそもの間違いでしょう。何度もいいますが、assertを出してくると言うことは
assert文があるはずです。あなたがコーディングしていなくてもMFCの内部とかにあるは
ずです。とにかく「中止」を押した時点でデバッグを放棄してしまっている(せっかくの
手がかりを見失っている)のだということを自覚してください。
で、
>中身「コーディング」すると、出なくなっちゃうんです
「出なくなった」ということを証明できるのならもう気にしなくていい、という考え方も
あります。「またいつか、何かの拍子に出てくるかもしれない」と不安に思うのなら
assertが出たその時に原因を追及するクセをつけるべきです。
自分の不注意が大きな原因ですので、
>「出なくなった」ということを証明できるのならもう気にしなくていい、
この考えで行きたいと思います
デバックに関してもうひとつ質問あるんですけど
別スレッド起こします
ご回答いただいた皆様ありがとうございました