7

問題をデバッグするための標準的な方法は何ですか?これはかなり広い質問のように思えるかもしれませんが、「問題によって異なります」と答える人もいますが、私たちの多くは本能的にデバッグし、実際にプロセスを表現しようとはしていません。そのため、「状況によって異なります」と言います。

最近、数人の開発者と私が同じ問題に取り組んでいて、まったく異なる方法でデバッグしていたため、私は自分のプロセスを言葉で表現することを余儀なくされました。私がやろうとしていることを彼らに理解してもらいたいと思いました。逆もまた同様です。

少し考えてみると、自分のデバッグ方法は実際には非常に単調であることがわかりました。まず、問題を確実に再現できるようにします(特にローカルマシンで)。次に、一連の除去を通じて(そして、これが問題に依存していると私が思うところです)、問題を特定しようとします。

他の人たちはまったく違う方法でそれをやろうとしていました。

だから、あなたたちのために何が働いているのか疑問に思っていますか?そして、それを言葉で形式化する必要がある場合、あなたのプロセスはデバッグのためのものだと思いますか?

ところで、私たちはまだ私たちの問題を発見していません=)

4

11 に答える 11

7

私のアプローチは、手元のシステムに精通していることによって異なります。通常、私は次のようなことをします。

  1. 可能であれば、障害を再現します。
  2. 障害状態を調べて、障害の直接の原因を特定します。
  3. 私がシステムに精通しているなら、私は根本的な原因について良い推測を持っているかもしれません。そうでない場合は、ソフトウェアによって行われた基本的な仮定に挑戦しながら、ソフトウェアを介してデータを機械的に追跡し始めます。
  4. 問題に一貫したトリガーがあると思われる場合は、コードが行う暗黙の仮定に挑戦しながら、デバッガーを使用してコードを手動で進めることができます。

もちろん、根本的な原因を突き止めることは、物事が毛むくじゃらになる可能性がある場所です。これは、ダンプ(またはより良い、ライブの壊れたプロセス)を持つことが本当に貴重な場合がある場所です。

私のデバッグプロセスの重要なポイントは、先入観や仮定に挑戦することだと思います。 そのコンポーネントに、私や同僚が正常に機能していると誓うバグを見つけた回数は膨大です。

私のより直感的な友人や同僚から、彼らが私をデバッグするのを見たり、何かを理解するのを手伝ってくれるように頼んだりすると、私はかなり衒学者だと言われました。:)

于 2009-04-08T03:57:34.050 に答える
4

David J Agans著の「Debugging 」という本を手に入れることを検討してください。副題は「最もとらえどころのないソフトウェアとハ​​ードウェアの問題を見つけるための 9 つの不可欠なルール」です。彼のデバッグ ルールのリスト — Web サイトのポスター形式で入手できます (本へのリンクもあります)。

  • システムを理解する
  • 失敗させる
  • 考えるのをやめて見る
  • 分割統治
  • 一度に 1 つのことを変更する
  • 監査証跡を残す
  • プラグを確認してください
  • 新しい視点を得る
  • あなたがそれを修正しなかった場合、それは修正されていません

最後のポイントは、ソフトウェア業界に特に関係があります。

于 2009-04-08T05:52:05.273 に答える
3

私はウェブ上でそれらを選んだか、思い出せない本をいくつか選びました(それはCodi​​ngHorrorだったかもしれません...)

101のデバッグ:

  • 再現する
  • プログレッシブナロースコープ
  • デバッガーを避ける
  • 一度に1つだけ変更する

心理学的方法:

  • ラバーダックデバッグ
  • 推測しないでください
  • ツールのせいにするのが早すぎないでください
  • 問題と解決策の両方を理解する
  • 休憩する
  • 複数の原因を検討する

バグ防止方法:

  • 独自のフォールトインジェクションの習慣を監視する
  • デバッグ支援を早期に導入する
  • ゆるい結合と情報隠蔽
  • 再発生を防ぐための回帰テストを作成する

技術的方法:

  • 不活性トレースステートメント
  • サードパーティ製品のログファイルを参照してください
  • Webでスタックトレースを検索します
  • 契約による設計の導入
  • スレートをきれいに拭きます
  • 断続的なバグ
  • Explot Localility
  • ダミーの実装とサブクラスを導入する
  • 再コンパイル/再リンク
  • プローブ境界条件と特殊なケース
  • バージョンの依存関係を確認する(サードパーティ)
  • 最近変更されたコードを確認してください
  • エラーメッセージを信用しないでください
  • グラフィックのバグ
于 2009-04-08T04:31:59.350 に答える
3

理解できないバグに直面したときは、問題のモデルを作成するのが好きです。問題のあるコードのセクションのコピーを作成し、一度に1つずつ機能の削除を開始します。削除するたびに、コードに対して単体テストを実行します。このプロセスを通じて、バグのある機能を削除するか(したがって、バグを特定します)、問題の本質を含むコードのコア部分にバグを分離します。そして、問題の本質を理解すると、修正がはるかに簡単になります。

于 2009-04-08T03:55:51.840 に答える
2

私は通常、手元にある情報に基づいて仮説を立てることから始めます。これが完了したら、それが正しいことを証明する作業を行います。それが間違っていることが判明した場合は、別の仮説から始めます。

マルチスレッド同期の問題のほとんどは、このアプローチで非常に簡単に解決されます。

また、使用しているデバッガとその機能をよく理解している必要があります。私は Windows アプリケーションに取り組んでおり、windbg がバグを見つけるのに非常に役立つことを発見しました。

于 2009-04-08T04:07:03.437 に答える
2

バグを最も単純な形に縮小することで、多くの場合、問題の理解が深まり、必要に応じて他の人を巻き込むことができるという利点が追加されます。

選択した仮説をテストするために時間を効率的に使用できるように、迅速な再現シナリオを設定します。

比較のために環境をすばやくダンプするツールを作成します。

ロギングを最大レベルにしてバグを作成および再現します。

システム ログを調べて、警告を発するものがないか調べます。

ファイルの日付とタイムスタンプを調べて、問題が最近発生した可能性があるかどうかを判断します。

関連するモジュールでの最近のアクティビティについて、ソース リポジトリを調べます。

演繹的な推論を適用し、Ockham's Razor の原則を適用します。

喜んで一歩下がって、問題から一休みしましょう。

于 2009-04-08T04:07:05.213 に答える
1

私は消去法を使うのも大好きです。変数を除外すると、デバッグ作業が大幅に簡素化されます。多くの場合、最初に行うべきことです。

もう 1 つの非常に効果的な手法は、可能であれば、最後に作業していたバージョンにロールバックして、もう一度やり直すことです。これは、より慎重に進むための強固な足場を提供するため、非常に強力です。これのバリエーションは、より多くの機能で動作しないよりも、より少ない機能で動作するポイントまでコードを取得することです。

もちろん、ただやってみるだけではないことは非常に重要です。それは決してうまくいかないので、これはあなたの絶望を増大させます。バグに関する情報を収集するために 50 回実行するほうがいいと思います。

于 2009-04-08T04:05:30.863 に答える
0

まだ初心者のためか、デバッグの方法が異なります。

論理的なバグに遭遇すると、最終的に変数を追加して、どの値がどこに行くのかを確認し、問題を引き起こしているコードの一部を 1 行ずつデバッグしていきます。

于 2009-04-08T04:37:09.337 に答える
0

問題を再現し、再現可能なテスト データ セットを生成することは、間違いなくデバッグの最初の最も重要なステップです。

再現性のあるバグを特定できれば、通常は、問題が見つかるまで関連するコンポーネントを特定しようとします。明確に述べることができるように、ケースを除外するのに少し時間を費やすことがよくあります。問題はコンポーネント X (またはプロセス Y など) にはありません。

于 2009-04-08T05:35:41.320 に答える
0

最初にエラーを再現しようとしますが、エラーを再現することができなければ、重要なプログラムで問題を推測することは基本的に不可能です。

次に、可能であれば、別のスタンドアロン プロジェクトでコードを分割します。これにはいくつかの理由があります: 元のプロジェクトが大きい場合、2 番目にデバッグするのが非常に難しく、コードに関する仮定が排除または強調されます。

私は通常、VS の別のコピーを常に開いており、これをミニ プロジェクトのデバッグ部分に使用し、後でメイン プロジェクトに追加するルーチンをテストします。

別のモジュールでエラーを再現すると、戦いはほぼ勝ちます。

コードの一部を分解するのが簡単でない場合があるため、そのような場合、問題の複雑さに応じてさまざまな方法を使用します。ほとんどの場合、データに関する仮定が私を悩ませているように見えるので、私の仮定が正しいことを確認するために、コードに多くのアサートを追加しようとします。また、エラーが消えるまで #ifdef を使用してコードを無効にします。他のモジュールなどへの依存関係を排除する...ハゲタカのようにバグをゆっくりと回っているようなもの..

私は実際にそれを行う意識的な方法を持っていないと思います.それはかなり異なります. 混乱しすぎないように願っています:)

于 2009-04-08T06:08:31.567 に答える