web-dev-qa-db-ja.com

複製できないバグをどのように修正しますか?

質問はそれをすべて言います。複数のユーザーが報告するバグがあるが、ログにバグの発生の記録がなく、バグを繰り返すことができない場合、どの程度の努力をしても、どのように修正すればよいですか?それともできますか?

これはあなた方の多くに起こったことだと思います。この状況であなたは何をしましたか、そして最終的な結果は何でしたか?


編集:私はnfindableバグについて何が行われたかに興味があります。解決できないバグではありません。解決できないバグは、少なくとも問題があることを知っていて、ほとんどの場合、それを検索するための開始点があるバグです。見つからない場合はどうしますか?何でもできる?

63
cdeszaq

これらは Heisenbugs として知られています。

言語

異なるプログラミング言語には、独自のバグの種類があります。

C

デバッグ文を追加すると、問題が発生する可能性があります 複製不可能 デバッグ文自体がポインタをシフトするため(SEGFAULTを回避するのに十分なほど)。ポインターの問題は追跡および複製するのが悪夢ですが、デバッガー( [〜#〜] gdb [〜#〜][〜#〜] ddd [〜#〜など)があります] )それが役立ちます。

Java

複数のスレッドを持つアプリケーションは、非常に特定のタイミングまたはイベントのシーケンスでのみバグを表示する場合があります。不適切な同時実行の実装は、複製が困難な状況でデッドロックを引き起こす可能性があります。

JavaScript

一部のWebブラウザは、メモリリークで悪名高い。あるブラウザーで正常に実行されるJavaScriptコードは、別のブラウザーで正しくない動作を引き起こす可能性があります。何千人ものユーザーによって厳密にテストされたサードパーティのライブラリを使用することは、特定のあいまいなバグを回避するのに有利です。

環境

アプリケーション(バグのある)が実行されている環境の複雑さによっては、環境を単純化することが唯一の手段となる場合があります。アプリケーションは実行されますか?

  • サーバー上?
  • デスクトップ上?
  • webブラウザで?

アプリケーションはどの環境で問題を引き起こしますか?

  • 開発?
  • テスト?
  • 製造?

無関係なアプリケーションを終了し、バックグラウンドタスクを終了し、スケジュールされたすべてのイベント(cronジョブ)を停止し、プラグインを削除し、ブラウザアドオンをアンインストールします。

ネットワーキング

ネットワーキングは非常に多くのアプリケーションに不可欠なので、

  • ワイヤレス信号を含む安定したネットワーク接続を確保します。
  • ソフトウェアはネットワーク障害の後に堅牢に再接続しますか?
  • ファイル記述子を解放するために、すべての接続が適切に閉じられますか?
  • 機械を使うべきではない人はいますか?
  • 不正なデバイスがマシンのネットワークと相互作用していますか?
  • 干渉を引き起こす可能性のある工場や無線塔が近くにありますか?
  • パケットサイズと周波数は公称範囲内ですか?
  • すべてのネットワークデバイスは、帯域幅を大量に使用するのに適していますか?

一貫性

できるだけ多くの未知数を排除します。

  • 建築コンポーネントを分離します。
  • 重要ではない、または問題のある(競合する)要素を削除します。
  • さまざまなアプリケーションモジュールを非アクティブ化します。

本番、テスト、開発のすべての違いを取り除きます。同じハードウェアを使用します。完全に同じ手順でコンピュータをセットアップします。一貫性が鍵となります。

ロギング

大量のログを使用して、イベントが発生した時間を関連付けます。明らかなエラー、タイミングの問題などがないかログを調べます。

ハードウェア

ソフトウェアに問題がないと思われる場合は、ハードウェア障害を検討してください。

  • 物理的なネットワーク接続はしっかりしていますか?
  • 緩んだケーブルはありますか?
  • チップは正しく装着されていますか?
  • すべてのケーブルの接続がきれいですか?
  • 作業環境は清潔で埃がありませんか?
  • 非表示のデバイスまたはケーブルがげっ歯類または 昆虫 によって損傷を受けていますか?
  • ドライブに不良ブロックはありますか?
  • CPUファンは作動していますか?
  • マザーボードはすべてのコンポーネントに電力を供給できますか? (CPU、ネットワークカード、ビデオカード、ドライブなど)
  • 電磁干渉 が原因か?

そして主に組み込み用:

  • 供給バイパスが不十分ですか?
  • ボードの汚染?
  • はんだ接合不良/リフロー不良?
  • 電源電圧が許容範囲外の場合、CPUはリセットされませんか?
  • 電源がRailsはI/Oポートからバックパワーされており、完全に放電しないため、リセットが不良ですか?
  • ラッチアップ?
  • フローティング入力ピン?
  • ロジックレベルのノイズマージンが不十分(場合によってはマイナス)ですか?
  • タイミングマージンが不十分(場合によってはマイナス)ですか?
  • すずひげ
  • 静電破壊?
  • ESDの混乱?
  • チップエラッタ?
  • インターフェースの誤用(I2Cオフボードや高出力信号がある場合など)?
  • レースコンディション?
  • 偽造コンポーネント?

ネットワークとローカル

アプリケーションをローカルで(つまり、ネットワークを介してではなく)実行するとどうなりますか?他のサーバーでも同じ問題が発生していますか?データベースはリモートですか?ローカルデータベースを使用できますか?

ファームウェア

ハードウェアとソフトウェアの間にはファームウェアがあります。

  • コンピュータのBIOSは最新ですか?
  • BIOSバッテリーは機能していますか?
  • BIOSクロックとシステムクロックは同期していますか?

時間と統計

タイミングの問題を追跡することは困難です。

  • 問題はいつ起こりますか?
  • どのくらいの頻度?
  • その時点で他にどのようなシステムが稼働していますか?
  • アプリケーションは時間に敏感ですか(たとえば、うるう日またはうるう秒は問題を引き起こしますか)?

問題に関する厳密な数値データを収集します。最初はランダムに見えるかもしれない問題でも、実際にはパターンがあるかもしれません。

変更管理

システムのアップグレード後に問題が発生する場合があります。

  • 問題が最初に始まったのはいつですか?
  • 環境(ハードウェアとソフトウェア)で何が変更されましたか?
  • 以前のバージョンにロールバックした後はどうなりますか?
  • 問題のあるバージョンと適切なバージョンの違いは何ですか?

ライブラリ管理

オペレーティングシステムによって、競合するライブラリを配布する方法が異なります。

  • WindowsにはDLL Hellがあります。
  • Unixには多数の壊れたシンボリックリンクが存在する可能性があります。
  • Javaライブラリファイルも同様に悪夢のように解決することができます。

オペレーティングシステムの新規インストールを実行し、アプリケーションに必要なサポートソフトウェアのみを含めます。

Java

すべてのライブラリが1回だけ使用されることを確認してください。アプリケーションコンテナには、アプリケーション自体とは異なるバージョンのライブラリが含まれている場合があります。これは、開発環境では複製できない可能性があります。

Maven または Ivy などのライブラリ管理ツールを使用します。

デバッグ中

バグが発生したときに通知をトリガーする検出メソッド(ログ、電子メール、ポップアップ、ポケットベルのビープ音など)をコーディングします。自動テストを使用して、アプリケーションにデータを送信します。ランダムデータを使用します。既知の可能性のあるEdgeケースをカバーするデータを使用します。最終的にはバグが再発するはずです。

Sleep

他の人が言ったことを繰り返すことは価値があります。問題から離れて時間を過ごし、他のタスク(ドキュメントなど)を完了します。コンピュータから物理的に離れて、いくつかの運動をしてください。

コードレビュー

コードを1行ずつ説明し、すべての行が自分自身、同僚、または rubber duck に対して何をするかを説明します。これは、バグの再現方法に関する洞察につながる可能性があります。

宇宙放射線

Cosmic Rays ビットを反転できます。メモリの最新のエラーチェックにより、これは過去の問題ほど大きくありません。地球の保護を離れるハードウェア用のソフトウェアは、宇宙放射線のランダム性のために複製できない問題の影響を受けます。

ツール

まれですが、特にニッチツール(たとえば、シンボルテーブルオーバーフローの影響を受けるCマイクロコントローラーコンパイラー)の場​​合に発生します。

77
Dave Jarvis

それがGUIアプリである場合、顧客がエラーを生成するのを監視する(または試行する)のは非常に重要です。彼らはあなたが彼らがやっていたことを決して想像もしなかった何かをしているのは間違いないだろう(間違ってではなく、ただ違うだけで)。

それ以外の場合は、そのエリアにロギングを集中させます。ほとんどすべてをログに記録し(後で引き出すことができます)、アプリに環境をダンプさせます。例えばマシンタイプ、VMタイプ、使用されるエンコーディング。

アプリはバージョン番号、ビルド番号などを報告しますか?これは、デバッグしているバージョンを正確に判別するために必要です(またはそうではない!)。

Java世界にいる場合はJMXを使用して)アプリを計測できる場合は、問題の領域を計測します。リクエスト+パラメータ、作成時間などの統計を保存します。最後の 'n'リクエスト/レスポンス/オブジェクトバージョン/何でも格納するバッファの数。ユーザーが問題を報告したときにそれらをダンプします。

13
Brian Agnew

複製できない場合は修正できますが、修正済みであることはわかりません。

バグがどのようにしてトリガーされたか(その状況がどうなるかわからなかった場合でも)について最善を尽くして説明し、それを修正して、バグが再び表面化した場合は、通知メカニズムによって将来の開発者ができるようにしました私が知っていたかったことを知っています。実際には、これは、バグをトリガーする可能性のあるパスが交差し、関連リソースのメトリックが記録されたときに、ログイベントを追加することを意味しました。そしてもちろん、テストがコードを一般的にうまく機能させることを確認します。

追加する通知を決定することは、実現可能性とトリアージの問題です。そのため、そもそもバグに費やす開発者の時間を決定しています。バグの重要性を知らずに答えることはできません。

私は良い結果(二度と表示されず、コードはそれに対して優れていた)と悪い結果(バグが修正されたかどうかに関係なく、問題を修正しないために多くの時間を費やした)がありました。そのために、見積もりと問題の優先順位が設定されています。

8
Karl Anderson

時々、バグを見つけるまで、ただ座ってコードを研究しなければなりません。バグが不可能であることを証明するようにしてください。その過程で、どこが間違っているのかを理解することができます。あなたが実際に自分自身を納得させることに成功した場合、それは不可能です、あなたがどこかで失敗したと仮定します。

一連のエラーチェックとアサーションを追加して、信念/仮定を確認または拒否することが役立つ場合があります。予期しないことが発生する可能性があります。

7
David

難しいこともあり、ほとんど不可能に近いこともあります。しかし、私の経験では、十分な時間を費やせば、遅かれ早かれバグを再現して修正できるようになります(その時間を費やす価値がある場合は、別の問題です)。

この状況で役立つかもしれない一般的な提案。

  • 可能であれば、さらにログを追加して、次回バグが発生したときにより多くのデータを取得できるようにします。
  • バグを再現できるかどうかをユーザーに尋ねます。もしそうなら、彼らに彼らの肩越しに見ながらそれを複製させることができ、うまくいけばバグの引き金となるものを見つけてください。
6
driis

何かがうまくいくまでランダムに変更してください:-)

4
Michael Wiles

考える。ハード。邪魔をせず、邪魔しないでください。

私はかつて、証拠が破損したデータベースの16進ダンプであるというバグがありました。ポインターのチェーンは体系的にねじ込まれていました。すべてのユーザーのプログラムとデータベースソフトウェアがテストで問題なく動作しました。私はそれを1週間見つめ(それは重要な顧客でした)、数十の考えられる可能性を排除した後、データが2つの物理ファイルに分散し、チェーンがファイルの境界を越えたところで破損が発生していることに気付きました。重要なポイントでバックアップ/復元操作が失敗した場合、2つのファイルが「非同期」になり、異なる時点に復元される可能性があることに気付きました。その後、既に破損したデータに対して顧客のプログラムの1つを実行すると、私が見ていたポインタの結び目チェーンが正確に生成されます。次に、破損を正確に再現する一連のイベントを示しました。

4
Michael Kay

問題が発生していると思われるコードを変更して、追加のデバッグ情報がどこかに記録されるようにします。それが次に起こるとき、あなたは問題を解決するためにあなたの必要性を持っているでしょう。

3
KM.

複製できないバグには2つのタイプがあります。あなたが発見した種類、および他の誰かが発見した種類。

バグを発見した場合は、それを複製できるはずです。それを複製できない場合は、バグにつながるすべての要因を考慮していないだけです。これが、バグがあるときはいつでも文書化する必要がある理由です。ログの保存、スクリーンショットの取得などを行います。保存しない場合は、バグが実際に存在することをどのように証明すればよいでしょうか?多分それは単なる虚偽の記憶ですか?

他の誰かがバグを発見し、それを複製できない場合は、明らかにそれを複製するように依頼してください。複製できない場合は、複製を試みます。すぐに複製できない場合は無視してください。

私はそれが悪いように聞こえることを知っていますが、それは正当化されると思います。他の誰かが発見したバグを複製するのにかかる時間は非常に長いです。バグが本当であれば、それは自然に再発します。誰か、おそらくあなたも、それをもう一度見つけます。複製が困難な場合は、それもまれであり、さらに数回発生しても、それほど大きな損傷を与えないでしょう。

実際の作業、他のバグの修正、新しいコードの作成に時間を費やすと、実際に存在することさえ保証できないミステリーバグを複製しようとするよりも、はるかに生産的になります。それが自然に再び現れるのを待つだけで、それを明らかにしようとするためにあなたの時間を無駄にするのではなく、あなたはそれを修正するためにあなたのすべての時間を費やすことができます。

3
Apreche

役立つと思われるすべてのロギングをすでに追加していて、それが役に立たなかったとすると、次の2つのことが思い浮かびます。

  1. 報告された症状から逆に作業します。自分自身について考えてください。「報告された症状を生成したかったのですが、実行する必要のあるコードのビットと、それをどのようにして達成し、どのようにしてそれを達成するのですか?」 DはCにつながり、BはAにつながります。バグが再現できない場合、通常の方法では解決できないことを受け入れます。いくつかのバグを見つけるために、この種の思考プロセスが進行している間、私は何時間もコードを見つめなければなりませんでした。通常、それは何か本当に愚かであることが判明します。

  2. ボブの最初のデバッグ法則を思い出してください。何かが見つからない場合、それは間違った場所を探しているためです。

3
Bob Moore

問題について話し合い、コードを読んでください。通常、分析の可能性を非常に迅速に排除できるため、多くの場合、ペアで行います。

2
krosenvold

まず、利用可能なツールを確認します。たとえば、WindowsプラットフォームでのクラッシュはWinQualに送られるため、これが当てはまる場合は、クラッシュダンプ情報が表示されます。潜在的なバグを見つける静的分析ツール、ランタイム分析ツール、プロファイリングツールを使用できますか?

次に、入力と出力を確認します。ユーザーがエラーを報告する状況での入力について何か類似したもの、または出力で不適切なものはありますか?レポートのリストをコンパイルして、パターンを探します。

最後に、Davidが述べたように、コードを見つめます。

2
Stephen Nutt

ユーザーに自分のコンピューターへのリモートアクセスを許可し、すべてを自分で確認するように依頼します。ユーザーにこのバグを再現する方法の小さなビデオを作成して送信するようユーザーに依頼します。

確かに両方が常に可能であるとは限りませんが、可能であれば、いくつかのことを明らかにするかもしれません。バグを見つける一般的な方法は同じです。バグを引き起こす可能性のある部分を分離し、何が起こっているのかを理解しようとし、バグを引き起こす可能性のあるコードスペースを狭めます。

1

Gotomeeting.comなどのツールを使用して、ユーザーと画面を共有し、動作を観察できます。マシンにインストールされているソフトウェアの数、プログラムと競合する一部のツールユーティリティなど、多くの潜在的な問題が発生する可能性があります。私はgotomeetingが唯一の解決策ではないと信じていますが、タイムアウトの問題、遅いインターネットの問題があるかもしれません。

ほとんどの場合、たとえばJavaおよびc#はすべての例外を追跡します。すべてをキャッチするのではなく、キャッチできるポイントを維持し、 log。UIのバグは、リモートデスクトップツールを使用しない限り解決が困難であり、ほとんどの場合、サードパーティのソフトウェアでもバグである可能性があります。

0
Akash Kava