- PR -

泥臭いデバック方法に関して

投稿者投稿内容
ToGo
常連さん
会議室デビュー日: 2002/03/16
投稿数: 46
投稿日時: 2004-12-23 19:35
アサーションを使うのがよさそうな状況かと思います。
設計の条件が甘いため、無効値(無効状態)を許してしまっている状況のようです。
設計条件をきちんと見直して(事前条件・事後条件の切り口が有効)、バグの原因
となっている個所を切り分けしていくとよさそうです。

デバッガだと滅多に現象がでない場合にバグを追い込むのが大変な作業になります。
ログ埋め込みだと、ログを実行毎に目視確認する作業が大変になります。

事件条件の洗い出し方はいろいろあるかと思いますが、引数それぞれについて、
有効範囲(上限値・下限値)を必ず決めること、コンストラクタで初期化して
いないフィールドがあればその内容をメソッド実行前にチェックするなどが
一般的かと思います。

JDK1.4+なら、assert文が使えます。
JDK1.3以前なら、if (isDebug) { ... } で囲んだ中に事前条件を判定する
コードを書く等の方法で対処します。

# AspectJを使うと、コードを直接いじらなくてもチェックロジックを入れら
# たりするのですが・・・。

(株)ぽち
ぬし
会議室デビュー日: 2002/09/10
投稿数: 376
投稿日時: 2004-12-24 10:19
デバッガを使う方がやはり多いようですね。

私が最初に言っていたプロファイラとは、JProveとかのアレです。
主にチューニングに使うのは知ってますが、このようなケースで
も使えるのかな?と思っていまして質問しました。

回答からは、使えないようですね。

現状では、どの業務パターンで発生するかなどの詳しい情報が
わからないそうなので、そちらの特定が先かもしれません。

なんとなく、試験のルート漏れで「参照」絡みのミスのような
気がしないでもないですが。

引用:

前川さんの書き込み (2004-12-23 00:42) より:
引用:
再現を待ち、再現したらログから解析

ってもしや、たまたま発生するまでひたすら叩く、という意味でしょうか。だとしたらデバッガもあまり向いているとは言えません。毎回止めてステップ実行していては効率が悪すぎるので。


そうですね。ログ埋めて、ひたすら再現まで待ってというイメージで書きました。

デバッガを使うのはもちろんローカル環境だと思うのですが、「たまたま」出るような
ケースだとその「ケース」を探るのに時間かかりそうです。

画面遷移でもそのような原因になる時ありますしね。
A→Bでは発生しないが、A→B→C→Bで発生するなど。

プロフェッショナルな方がいれば、ソースをレビューしてもらうなどの手段も
あるとのことですが、そのような方もなかなかおらず。
また、たった一つのバグのためにそのような方を呼び寄せるとかも費用が
かさみます。

また、別の疑問なのですが、上記のようにどの「業務・入力ケースで」が特定
できていない場合、皆さんはまず何をされますか?

・現象を分析して業務・入力ケースの特定?
・おおまかな業務で考えて、それに関連する試験を見直し、再試験?
・ログ埋め込みなおして再現待ち?
シュン
ぬし
会議室デビュー日: 2004/01/06
投稿数: 328
お住まい・勤務地: 東京都
投稿日時: 2004-12-24 12:26
ええと、[条件付]ブレークポイント設定がお勧めですよ。
デバッガは、変数が特定の条件式でtrueを返すとき[だけ]停止するというブレー
クポイントを張ることができるのです。

コード:

if (hoge == null) {
// ここでモーダルダイアログを出して止まる(GUI アプリケーションなら)。
// あるいはデバッガーでブレークポイントを設定しておく。
}



このようなコードの挿入+リコンパイルの作業が必要ないので、ソースコードの改変が
しにくい状況の場合でも無問題です。デバッグの対象プロセスをデバッグモードで実行して
おくことが可能かどうかだけがネックになります。

マルチスレッドに起因するバグなど、稀にしか起きないバグの解析に用いることが出来ます。
スレッド間のデッドロックのような現象も、ロック発生時点での各変数のインスペクトが
できるので、スレッドダンプの解析より一歩踏み込んだ解析が出来ます。是非一度お試し
ください。
#但し、マルチスレッドに起因するバグは、デバッグモードで実行していることが原因で、
#起きなくなる可能性があるので注意が必要ですけれど。

対象プログラムがJ2EEアプリで、デプロイ先のAPサーバーが「テスト専用サーバー」かつ
多少の性能劣化が問題にならないならば、リモートデバッグ可能な状態で一度再起動して
おいて、後はその状態のままにしておくのもよいかと。
何か起きたら、そのたびに毎回デバッガからアタッチして情報収集ができます。

それと、OraclePreparedStatementは、メンバ変数にSQL文を持っていた記憶があります
ので、デバッガでインスペクトできた覚えがあります。JDBCドライバの実装依存ですので
確証はありませんが…
#私の場合SQLがらみの調査がしたい場合は、JDBCのインターフェイスにデコレーターパ
#ターンでフックしてSQL文を取り出してログにはくような、簡単な汎用JDBCラッパーを書
#いてしまうことが多いですね。


[ メッセージ編集済み 編集者: シュン 編集日時 2004-12-24 12:41 ]
yuu
大ベテラン
会議室デビュー日: 2002/06/12
投稿数: 152
お住まい・勤務地: 美味しいケーキ店のそば
投稿日時: 2004-12-24 14:07
こんにちは

>プロフェッショナルな方がいれば、ソースをレビューしてもらうなどの手段も
あるとのことですが、そのような方もなかなかおらず。

別にレベルの高い人でなくとも、同じくらいのレベルの人でも他人にレビューしてもらうのは有効だと思いますが・・・

>「業務・入力ケースで」が特定できていない場合、皆さんはまず何をされますか?
お客様しだいではないでしょうか

・その問題によって、お客様がすごく困ってる(怒ってる)場合は、半日・1日でも良いからテスター(開発者や事務の人でもOK)をかき集め、ログ入りソフトで再現テストを行うとか、
または、お客様のところで半日に1回とか再現するようなら、お客様のところでログ入りソフトに入れ替え 再現を待つとか・・・

・実はその問題は、お客様はあまり重要でないと思ってる(または、耐えられるなら) そのまま再現待ちとか

お客様がシステムに不安を持たないようにする事が重要かなと思います。
マーサ
ベテラン
会議室デビュー日: 2004/11/26
投稿数: 87
投稿日時: 2004-12-24 14:31
引用:

また、別の疑問なのですが、上記のようにどの「業務・入力ケースで」が特定
できていない場合、皆さんはまず何をされますか?

・現象を分析して業務・入力ケースの特定?
・おおまかな業務で考えて、それに関連する試験を見直し、再試験?
・ログ埋め込みなおして再現待ち?



基本的には発生条件を特定させる事が先決だと思います。
実際に何をした時に発生したのか、入力条件等情報を収集しログと合わせて解析する。
条件がわからなければ、発生したと思われるルートを試験してみる。

中々発生しないようなケースであれば、ある程度分かっている範囲でログを埋め込み再現待ちをします。発生時に何を入力(操作)したらおこったかを明確にしてもらいます。


全く同じ条件で発生する場合と発生しない場合があるのであれば、解析はとても困難なことになると思います。(作成したプログラム以外の物が影響している場合も考えられますので。)
何かしらの違い(入力値やタイミング)が有るはずなので、それを特定させ無ければ先に進むことは難しい物になるでしょう。

簡単に書くと以下の手順になるかと・・・。
1.発生した際の操作及び情報収集。
2.発生条件を特定する。(ログが足りなければ追加で盛り込む)
3.現象と改修コストをお客様に報告する。
4.改修しリリースする。

発生し難いものはどうしてもログを埋め込み再現待ちとなるかと思います。。。
(株)ぽち
ぬし
会議室デビュー日: 2002/09/10
投稿数: 376
投稿日時: 2004-12-24 15:13
引用:

全く同じ条件で発生する場合と発生しない場合があるのであれば、解析はとても困難なことになると思います。(作成したプログラム以外の物が影響している場合も考えられますので。)
何かしらの違い(入力値やタイミング)が有るはずなので、それを特定させ無ければ先に進むことは難しい物になるでしょう。



例えば、「戻る」ボタン押下してからとか、結果ページで右クリック「最新の情報に
更新」とか、重くて画面が表示できませんエラーからF5による再試行とか、レアな
ケースに起こる事象がWebシステムではいつも悩まされますが。。
マーサ
ベテラン
会議室デビュー日: 2004/11/26
投稿数: 87
投稿日時: 2004-12-24 15:32
引用:

例えば、「戻る」ボタン押下してからとか、結果ページで右クリック「最新の情報に
更新」とか、重くて画面が表示できませんエラーからF5による再試行とか、レアな
ケースに起こる事象がWebシステムではいつも悩まされますが。。



ありありですね^^;

基本的に「戻る」や「最新の情報に更新(F5)」の操作を行ったら動作保証しませんよなりの対処(設計段階で仕様とする)が必要です。
#私はそうして逃げていますw
とは言え、押される可能性は有るのでエラー画面を表示するなりして、最低限おかしな動作をする事は防ぎます。

対応してくれと言うのであれば、それなりのコーディングをするしかないですが・・・。

[ メッセージ編集済み 編集者: マーサ 編集日時 2004-12-24 15:36 ]
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2004-12-24 19:04
unibon です。こんにちわ。

引用:

シュンさんの書き込み (2004-12-24 12:26) より:
ええと、[条件付]ブレークポイント設定がお勧めですよ。
デバッガは、変数が特定の条件式でtrueを返すとき[だけ]停止するというブレー
クポイントを張ることができるのです。

コード:
if (hoge == null) {
    // ここでモーダルダイアログを出して止まる(GUI アプリケーションなら)。
    // あるいはデバッガーでブレークポイントを設定しておく。
}



このようなコードの挿入+リコンパイルの作業が必要ないので、ソースコードの改変が
しにくい状況の場合でも無問題です。デバッグの対象プロセスをデバッグモードで実行して
おくことが可能かどうかだけがネックになります。


昔の記憶なのですが、条件付きブレークポイントだと、実行速度が遅くなったような気がします。そのため私はほとんど使ったことがないです(最近は違うのかもしれませんが)。
あと、デバッガーがなんとなく信用できなくて、というのもあります。if 文を組み込んでその中の行に対して設定した無条件ブレークポイントならばほぼ信用できるのですが。でもこれすら信用できなくてさらに System.out.println まで埋め込んでしまうこともあります。う〜ん、我ながら泥臭い...(タイトルどおりだ)

スキルアップ/キャリアアップ(JOB@IT)