質問はそれをすべて言います。複数のユーザーが報告するバグがあるが、ログにバグの発生の記録がなく、バグを繰り返すことができない場合、どの程度の努力をしても、どのように修正すればよいですか?それともできますか?
これはあなた方の多くに起こったことだと思います。この状況であなたは何をしましたか、そして最終的な結果は何でしたか?
編集:私はnfindableバグについて何が行われたかに興味があります。解決できないバグではありません。解決できないバグは、少なくとも問題があることを知っていて、ほとんどの場合、それを検索するための開始点があるバグです。見つからない場合はどうしますか?何でもできる?
これらは Heisenbugs として知られています。
異なるプログラミング言語には、独自のバグの種類があります。
デバッグ文を追加すると、問題が発生する可能性があります 複製不可能 デバッグ文自体がポインタをシフトするため(SEGFAULTを回避するのに十分なほど)。ポインターの問題は追跡および複製するのが悪夢ですが、デバッガー( [〜#〜] gdb [〜#〜] や [〜#〜] ddd [〜#〜など)があります] )それが役立ちます。
複数のスレッドを持つアプリケーションは、非常に特定のタイミングまたはイベントのシーケンスでのみバグを表示する場合があります。不適切な同時実行の実装は、複製が困難な状況でデッドロックを引き起こす可能性があります。
一部のWebブラウザは、メモリリークで悪名高い。あるブラウザーで正常に実行されるJavaScriptコードは、別のブラウザーで正しくない動作を引き起こす可能性があります。何千人ものユーザーによって厳密にテストされたサードパーティのライブラリを使用することは、特定のあいまいなバグを回避するのに有利です。
アプリケーション(バグのある)が実行されている環境の複雑さによっては、環境を単純化することが唯一の手段となる場合があります。アプリケーションは実行されますか?
アプリケーションはどの環境で問題を引き起こしますか?
無関係なアプリケーションを終了し、バックグラウンドタスクを終了し、スケジュールされたすべてのイベント(cronジョブ)を停止し、プラグインを削除し、ブラウザアドオンをアンインストールします。
ネットワーキングは非常に多くのアプリケーションに不可欠なので、
できるだけ多くの未知数を排除します。
本番、テスト、開発のすべての違いを取り除きます。同じハードウェアを使用します。完全に同じ手順でコンピュータをセットアップします。一貫性が鍵となります。
大量のログを使用して、イベントが発生した時間を関連付けます。明らかなエラー、タイミングの問題などがないかログを調べます。
ソフトウェアに問題がないと思われる場合は、ハードウェア障害を検討してください。
そして主に組み込み用:
アプリケーションをローカルで(つまり、ネットワークを介してではなく)実行するとどうなりますか?他のサーバーでも同じ問題が発生していますか?データベースはリモートですか?ローカルデータベースを使用できますか?
ハードウェアとソフトウェアの間にはファームウェアがあります。
タイミングの問題を追跡することは困難です。
問題に関する厳密な数値データを収集します。最初はランダムに見えるかもしれない問題でも、実際にはパターンがあるかもしれません。
システムのアップグレード後に問題が発生する場合があります。
オペレーティングシステムによって、競合するライブラリを配布する方法が異なります。
オペレーティングシステムの新規インストールを実行し、アプリケーションに必要なサポートソフトウェアのみを含めます。
すべてのライブラリが1回だけ使用されることを確認してください。アプリケーションコンテナには、アプリケーション自体とは異なるバージョンのライブラリが含まれている場合があります。これは、開発環境では複製できない可能性があります。
Maven または Ivy などのライブラリ管理ツールを使用します。
バグが発生したときに通知をトリガーする検出メソッド(ログ、電子メール、ポップアップ、ポケットベルのビープ音など)をコーディングします。自動テストを使用して、アプリケーションにデータを送信します。ランダムデータを使用します。既知の可能性のあるEdgeケースをカバーするデータを使用します。最終的にはバグが再発するはずです。
他の人が言ったことを繰り返すことは価値があります。問題から離れて時間を過ごし、他のタスク(ドキュメントなど)を完了します。コンピュータから物理的に離れて、いくつかの運動をしてください。
コードを1行ずつ説明し、すべての行が自分自身、同僚、または rubber duck に対して何をするかを説明します。これは、バグの再現方法に関する洞察につながる可能性があります。
Cosmic Rays ビットを反転できます。メモリの最新のエラーチェックにより、これは過去の問題ほど大きくありません。地球の保護を離れるハードウェア用のソフトウェアは、宇宙放射線のランダム性のために複製できない問題の影響を受けます。
まれですが、特にニッチツール(たとえば、シンボルテーブルオーバーフローの影響を受けるCマイクロコントローラーコンパイラー)の場合に発生します。
それがGUIアプリである場合、顧客がエラーを生成するのを監視する(または試行する)のは非常に重要です。彼らはあなたが彼らがやっていたことを決して想像もしなかった何かをしているのは間違いないだろう(間違ってではなく、ただ違うだけで)。
それ以外の場合は、そのエリアにロギングを集中させます。ほとんどすべてをログに記録し(後で引き出すことができます)、アプリに環境をダンプさせます。例えばマシンタイプ、VMタイプ、使用されるエンコーディング。
アプリはバージョン番号、ビルド番号などを報告しますか?これは、デバッグしているバージョンを正確に判別するために必要です(またはそうではない!)。
Java世界にいる場合はJMXを使用して)アプリを計測できる場合は、問題の領域を計測します。リクエスト+パラメータ、作成時間などの統計を保存します。最後の 'n'リクエスト/レスポンス/オブジェクトバージョン/何でも格納するバッファの数。ユーザーが問題を報告したときにそれらをダンプします。
複製できない場合は修正できますが、修正済みであることはわかりません。
バグがどのようにしてトリガーされたか(その状況がどうなるかわからなかった場合でも)について最善を尽くして説明し、それを修正して、バグが再び表面化した場合は、通知メカニズムによって将来の開発者ができるようにしました私が知っていたかったことを知っています。実際には、これは、バグをトリガーする可能性のあるパスが交差し、関連リソースのメトリックが記録されたときに、ログイベントを追加することを意味しました。そしてもちろん、テストがコードを一般的にうまく機能させることを確認します。
追加する通知を決定することは、実現可能性とトリアージの問題です。そのため、そもそもバグに費やす開発者の時間を決定しています。バグの重要性を知らずに答えることはできません。
私は良い結果(二度と表示されず、コードはそれに対して優れていた)と悪い結果(バグが修正されたかどうかに関係なく、問題を修正しないために多くの時間を費やした)がありました。そのために、見積もりと問題の優先順位が設定されています。
時々、バグを見つけるまで、ただ座ってコードを研究しなければなりません。バグが不可能であることを証明するようにしてください。その過程で、どこが間違っているのかを理解することができます。あなたが実際に自分自身を納得させることに成功した場合、それは不可能です、あなたがどこかで失敗したと仮定します。
一連のエラーチェックとアサーションを追加して、信念/仮定を確認または拒否することが役立つ場合があります。予期しないことが発生する可能性があります。
難しいこともあり、ほとんど不可能に近いこともあります。しかし、私の経験では、十分な時間を費やせば、遅かれ早かれバグを再現して修正できるようになります(その時間を費やす価値がある場合は、別の問題です)。
この状況で役立つかもしれない一般的な提案。
何かがうまくいくまでランダムに変更してください:-)
考える。ハード。邪魔をせず、邪魔しないでください。
私はかつて、証拠が破損したデータベースの16進ダンプであるというバグがありました。ポインターのチェーンは体系的にねじ込まれていました。すべてのユーザーのプログラムとデータベースソフトウェアがテストで問題なく動作しました。私はそれを1週間見つめ(それは重要な顧客でした)、数十の考えられる可能性を排除した後、データが2つの物理ファイルに分散し、チェーンがファイルの境界を越えたところで破損が発生していることに気付きました。重要なポイントでバックアップ/復元操作が失敗した場合、2つのファイルが「非同期」になり、異なる時点に復元される可能性があることに気付きました。その後、既に破損したデータに対して顧客のプログラムの1つを実行すると、私が見ていたポインタの結び目チェーンが正確に生成されます。次に、破損を正確に再現する一連のイベントを示しました。
問題が発生していると思われるコードを変更して、追加のデバッグ情報がどこかに記録されるようにします。それが次に起こるとき、あなたは問題を解決するためにあなたの必要性を持っているでしょう。
複製できないバグには2つのタイプがあります。あなたが発見した種類、および他の誰かが発見した種類。
バグを発見した場合は、それを複製できるはずです。それを複製できない場合は、バグにつながるすべての要因を考慮していないだけです。これが、バグがあるときはいつでも文書化する必要がある理由です。ログの保存、スクリーンショットの取得などを行います。保存しない場合は、バグが実際に存在することをどのように証明すればよいでしょうか?多分それは単なる虚偽の記憶ですか?
他の誰かがバグを発見し、それを複製できない場合は、明らかにそれを複製するように依頼してください。複製できない場合は、複製を試みます。すぐに複製できない場合は無視してください。
私はそれが悪いように聞こえることを知っていますが、それは正当化されると思います。他の誰かが発見したバグを複製するのにかかる時間は非常に長いです。バグが本当であれば、それは自然に再発します。誰か、おそらくあなたも、それをもう一度見つけます。複製が困難な場合は、それもまれであり、さらに数回発生しても、それほど大きな損傷を与えないでしょう。
実際の作業、他のバグの修正、新しいコードの作成に時間を費やすと、実際に存在することさえ保証できないミステリーバグを複製しようとするよりも、はるかに生産的になります。それが自然に再び現れるのを待つだけで、それを明らかにしようとするためにあなたの時間を無駄にするのではなく、あなたはそれを修正するためにあなたのすべての時間を費やすことができます。
役立つと思われるすべてのロギングをすでに追加していて、それが役に立たなかったとすると、次の2つのことが思い浮かびます。
報告された症状から逆に作業します。自分自身について考えてください。「報告された症状を生成したかったのですが、実行する必要のあるコードのビットと、それをどのようにして達成し、どのようにしてそれを達成するのですか?」 DはCにつながり、BはAにつながります。バグが再現できない場合、通常の方法では解決できないことを受け入れます。いくつかのバグを見つけるために、この種の思考プロセスが進行している間、私は何時間もコードを見つめなければなりませんでした。通常、それは何か本当に愚かであることが判明します。
ボブの最初のデバッグ法則を思い出してください。何かが見つからない場合、それは間違った場所を探しているためです。
問題について話し合い、コードを読んでください。通常、分析の可能性を非常に迅速に排除できるため、多くの場合、ペアで行います。
まず、利用可能なツールを確認します。たとえば、WindowsプラットフォームでのクラッシュはWinQualに送られるため、これが当てはまる場合は、クラッシュダンプ情報が表示されます。潜在的なバグを見つける静的分析ツール、ランタイム分析ツール、プロファイリングツールを使用できますか?
次に、入力と出力を確認します。ユーザーがエラーを報告する状況での入力について何か類似したもの、または出力で不適切なものはありますか?レポートのリストをコンパイルして、パターンを探します。
最後に、Davidが述べたように、コードを見つめます。
ユーザーに自分のコンピューターへのリモートアクセスを許可し、すべてを自分で確認するように依頼します。ユーザーにこのバグを再現する方法の小さなビデオを作成して送信するようユーザーに依頼します。
確かに両方が常に可能であるとは限りませんが、可能であれば、いくつかのことを明らかにするかもしれません。バグを見つける一般的な方法は同じです。バグを引き起こす可能性のある部分を分離し、何が起こっているのかを理解しようとし、バグを引き起こす可能性のあるコードスペースを狭めます。
Gotomeeting.comなどのツールを使用して、ユーザーと画面を共有し、動作を観察できます。マシンにインストールされているソフトウェアの数、プログラムと競合する一部のツールユーティリティなど、多くの潜在的な問題が発生する可能性があります。私はgotomeetingが唯一の解決策ではないと信じていますが、タイムアウトの問題、遅いインターネットの問題があるかもしれません。
ほとんどの場合、たとえばJavaおよびc#はすべての例外を追跡します。すべてをキャッチするのではなく、キャッチできるポイントを維持し、 log。UIのバグは、リモートデスクトップツールを使用しない限り解決が困難であり、ほとんどの場合、サードパーティのソフトウェアでもバグである可能性があります。