再現性のない/ランダムに発生するバグを修正するにはどうすればよいですか?


11

数日前にバグが発見された多言語のウェブサイトがあります。他の言語のデータを他の言語で表示し、英語などのデータの混合も選択されていましたが、ページにも他の言語のデータが表示されていました。それはまれですが、ウェブサイトに存在します。これは常に発生するわけではないため、コードを調べても役に立ちません。

問題をタイムリーに見つけるための提案はありますか?ここで戦略を求めています。


4
このバグが発生する可能性がある状況でコードの調査を開始します(逆の方法ではなく)
Imran Omar Bukhsh

回答:


20

最初のステップは、このタイプの問題を引き起こす可能性のあるものを試行し、特徴付けることです。これは、コードのセクションに正しい言語を選択することに関連しているため、次のことを考慮することから始めます。

  • 言語はどのように検出されますか? HTTPリクエストからの情報に基づいていますか?セッション情報に基づいていますか?またはデータベースフィールドに基づいていますか?本質的に、これはアプリが各セクションの言語を選択する方法に関連する問題になりますか?
  • 言語はどのように表示されますか? プロパティファイルまたはデータベースからプルしていますか?正しい言語への参照が何らかの方法で失われている可能性はありますか?表示される混合言語は常にサイトのデフォルトですか?
  • クライアント環境と相関関係はありますか? これは最初の箇条書きに関連していますが、もう少し先に進みます。ダウンストリームキャッシングプロキシが原因で、奇妙なレンダリングの問題が発生しました。通常、これらの種類の問題は、ページ全体が古くなっているか、あるユーザーのページを他のユーザーに提供している(恥ずかしい)ものです。
  • スレッドローカル値を使用していますか? リクエストが複数のスレッドで処理される場合、スレッドローカル値には、その時点で動作しているスレッドに基づいて異なる情報が含まれます。Webサーバー環境では、プラットフォームの仕様の一部である場合を除き、処理を開始したスレッドが処理を完了したスレッドと同じであると想定することはできません。サーバーライターは、スレッドの小さなプールを再利用し、それらをチャンクで多重化すると、より多くの要求を同時に処理できることを発見しました。リクエストの開始から終了まで1つのスレッドがある場合でも、サーバーはそのスレッドに他のリクエストを同時に多重化している可能性があります。スレッドローカルの代わりに、その値を要求またはセッション属性にバインドすることを検討してください。

さて、何がうまくいかない可能性を特定したら、今度は、何がうまくいかなかったかを調べるために必要なデータがあることを確認します。

  • 問題のある領域で大量のログを記録します。これは、Log4JやLog4Netのようなツールが本当に輝く場所です。このログフレームワークなどのログフレームワークを使用すると、構成ファイルを変更することで、他のすべてのノイズを抑えながら、特定のカテゴリのログを有効にできます。疑わしいものが問題である可能性があるかどうかを判断するために、新しいロギングステートメントを導入する必要があります。また、HTTPアクセスログに、各リクエストについて必要なすべての情報(Cookie、HTTPヘッダーパラメーターなど)が含まれていることを確認してください。
  • 問題をシミュレートしようとします。これは散発的に発生するため、発生時のサーバーの負荷はどのくらいですか?さまざまな言語からの多数の同時リクエストに見舞われていますか?その場合、テスト環境でそのような負荷をシミュレートしてみてください。JMeterに似たツールが必要かもしれません。また、偽のクライアントのIPアドレスをスプーフィングできるようにする必要があります。IPアドレスは、アドレスの最初の2つのセグメントに基づいてIPがどの国/地域であるかを把握できるように分割されていることに注意してください。
  • 問題はテスト環境でも散発的に発生しますが、実際の原因に絞り込むと、結果を歪曲して、実際の原因よりも頻繁に発生させることができます。さらに、ログファイルをより簡単に確認して、そこから学習を試みることができます。
  • 繰り返しのプロセスなので、我慢してください。バグを再現し、ログを確認し、見つかった内容に基づいてテストを調整することになると思われる種類の負荷を誘導する必要があります。重要なことは、問題特定することです。そのため、実際の問題の発生頻度を減らすだけの簡単な修正を行う衝動に抵抗してください。

最後に、問題の再現方法と原因を把握できるまで問題を絞り込んだら、コードで問題を強制できる最小の自動テストを作成します。問題を1つのクラスに絞り込んだ場合、またはクラスのペアが正しく機能しない場合は、そのレベルで再現します。100個のスレッドを生成する必要はありません。問題を100%発生させることができる最小のテストを実行するだけです。

今、あなたはそれを修正することができ、それが再びあなたを噛むために戻ってこないことを合理的に確信することができます。


10

バグは非生産的ではありません。あなたはまだそれを再現する方法を見つけていません。

Random()ステートメントの戻り値に基づいて例外をスローしない限り、バグはランダムではありません。

これはセマンティクスのように見えるかもしれませんが、自分にこれを伝えることは精神的に安心です。

複雑な競合状態などが原因でのみ発生するバグを再現する方法を見つけることは、非常に困難でイライラします。

それを見つける方法については、より多くの情報を提供できる場所でアプリケーションのロギングをオン/追加します。

次に、バグを見ている人(開発者、QA、エンドユーザー)に、バグが発生した時点ですぐに報告するよう伝え、ログを調べます。他の情報を求めてください。バグはいくつかの異なるシステムの相互作用または競合状態が原因でのみ発生する可能性があります。

うまくいけば、リードを見つけることができるでしょう。


Random()呼び出しでさえ、ハードウェアホワイトノイズジェネレーターから派生しない限り、真にランダムではありません。それらは擬似乱数です。つまり、数字は数学的に可能な限りランダムな順序で分布しています。ただし、同じ「シード」値から開始すると、毎回同じ答えが得られます。
ベリンロリチュ

1
@ベリン:知っている。
ジル

「まだ再現方法がわかっていない」ための+1。すべてのバグには根本的な原因があるか、そうでない場合は発生しません。
マイクS

1
Random()をオフにする必要はありません。タイミングに依存するもの、特に共有リソースへの不適切なアクセスを含むものは、再現が非常に困難です。
ローレンペクテル

2
@Gilles:合理的に測定できるものについて決定論的でない場合があります。(言う、正確に他のタスクがタイムスライスをリリースしたとき。)
ローレンペクテル

5

問題が発生したことを認識することができるコード内の場所を見つけて(たとえば、メソッド内の一貫性のないパラメーター)、コードにチェックを追加し、デバッグログに追加情報を追加できます(スタックトレース、オブジェクトなど)セッションへの追加など)

少しの運でこれを行うと、発生に関する情報を取得し、問題に戻る方法を推測できます。


2

再現が同じ手順で失敗することがある場合は、自動化が役立ち、それを自動化してループに入れる必要があります。50,000回実行すると、発生する可能性が非常に高くなります。


イベントはランダムではなく、ランダムに見えるだけです。これを実行すると表示される場合がありますが、表示された理由に関する情報はほとんどありません。
ジョシュK

1
@Josh-彼がそれを再現できない場合、これはそれを実行し、たとえばデバッグシンボルでスタックトレースを取得する良い方法かもしれません。私はそれが素晴らしい最初のステップだと思います-それを直接見る
キーレン・ジョンストン

あなたはスタックがあり、それが入手可能であると仮定しています。彼は、アプリケーションに関する技術情報や、この種の負荷の下でデバッグするためのアクセス可能性については提供していません。これはデバッグ戦略ではありません。これは、それが壊れる正確な瞬間をキャッチしようとしてハンマーで叩いています。
ジョシュK

@ジョシュ-私の実世界の経験は、バグを調査/修正する上で最も価値のあることは、実際にそれを見ることです。タイミングがわかるもの、スタックトレース、ログ内の何か、その他何でも。可能であれば、ループ内で一見ランダムに発生する問題をテストすることで、実際に非常に迅速に対応できました。別のアイデアがある場合は、キリストのためにそれを回答として投稿してください。これは有効な方法であり、有効な回答です。
キーレンジョンストン

私は反対し、ベリンの答えがこれを解決する正しい方法であると信じています。
ジョシュK

1

この問題を明示する条件を特定するためのパターンを見つけてください。これは、失敗する(または一貫性のない動作をする)コードのセクションに向けられるはずです。


たわごとはない..............
theringostarrs

0

問題発生していることを検出できますか?その場合、その時点でのシステムの状態に関する情報を確実にダンプできますか?

これらの質問の両方に対する答えが「はい」である場合、実際にエラーが発生したときにできる限り多くの情報を記録するようにコードをインスツルメントし、待機します。

これは、他の人が提案したものに代わるものではありません(コードが表示されている状態に到達する方法を推論する必要があります)が、バグを自由に再現できない限り、出現する機会を無駄にしないことをお勧めします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.