最も効果的にコードをデバッグする方法は?[閉まっている]


33

コードに忍び寄るバグは最小限に抑え、それが書かれている通り、完全に解消されないことができます-プログラマがあり、多くのだろうが反対し、人間だけを。

コードでエラーを検出した場合、それを取り除くために何ができますか?貴重な時間を最も有効に活用し、それを見つけようとする時間を短縮し、より多くの時間をコーディングできるようにするには、どのようにアプローチする必要がありますか?また、デバッグするときは何を避けるべきですか?

ここで、バグの防止については話していないことに注意してください。バグ発生した場合の対処方法について説明してます。これは広い分野であり、言語、プラットフォーム、ツールに大きく依存している可能性があります。もしそうなら、考え方や一般的な方法などの回答を網羅してください。


リンクされた質問は削除されました。

1
アプローチは実際にはシンプルだと思います。単独で開発した場合、それに関するすべてを知っています。デバッグせずにバグを修正することもできます。それを念頭に置いて、それをよく知っている誰かがそれを修正する方法に関するあなたの質問に答えることができるまで、何か他のものをコーディングする時間を使うことが最善の方法です。または、それを修正するアイデアが思い浮かぶまで、他のことをコーディングして、時間もエネルギーも失うことはありません。私の推測では、あなたの質問は企業チームの管理に関するものです。
アクエリアスパワー14年

レイドだと思う。既製のバグを殺すスプレー。これは哲学的な質問ですか?本は単なる優勢から作られています...
ejbytes

回答:


38

デバッグに対する考え方と態度は、おそらく最も重要な部分です。これは、エラーをどの程度効果的に修正するか、そしてもしあればそれから何を学ぶかを決定するからです。

The Pragmatic Programmer and Code Completeのようなソフトウェア開発の古典は、基本的に同じアプローチを主張しますすべてのエラーは、ほとんど常に自分自身について学ぶ機会です(初心者のみがコンパイラ/コンピューターを最初に責めるため)。

クラックするのが面白いミステリーとして扱いましょう。そして、(自分自身または他者に)仮定を表現し、必要に応じて仮定をテストすることにより、その謎を体系的に行う必要があります。その後、謎が解決した後、あなたが行った可能性のある同様のエラーについてすべてのコードを調べることで、さらに改善することができます。自動テストを作成して、エラーが無意識のうちに再び発生しないことを確認します。

最後の注意-エラーを「バグ」ではなく「エラー」と呼びたい見て、私たち自身の(ずさんな)思考のためにそこにいる代わりに:http : //www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EWD1036.html

たとえば、バグをバグと呼ぶのではなく、エラーと呼ぶことで、言語をクリーンアップすることから始めることができます。それは、それが属する場所に非難を正に置くので、はるかに正直です、すなわち。エラーを起こしたプログラマーと。プログラマが見ていなかった間に悪意を持って侵入したバグのアニミスティックな隠metaは、エラーがプログラマ自身の作成であると偽装するため、知的に不正です。語彙のこの単純な変更の良いところは、そのような深遠な効果があることです。以前は、バグが1つだけのプログラムは「ほぼ正しい」ものでしたが、その後、エラーのあるプログラムは単に「間違っています」エラー)。


7
実際、「バグ」よりも「エラー」という用語が好きです。「エラーを起こしたプログラマー」を責めているからではなく、それがプログラマーのせいではないことを明確にするためです。私にとって、「バグ」はコードのエラーを意味します。一方、「エラー」はどこかでエラーを意味します。たぶん、コードの中、環境設定の中、要件の中かもしれません。上司が問題の半分が要件の変更である「バグリスト」を持っているとき、私を夢中にさせます。それをタスクリストと呼びます。
Carson63000

2
+1「すべてのエラーは学習の機会であり、ほとんどの場合、自分自身について(初心者のみがコンパイラ/コンピューターを最初に責めるため)」
Md Mahbubur Ra​​hman

「バグ」という言葉の歴史を知っていますよね?つまり、ソフトウェア開発で使用されるように。もちろん、今日はこの問題はありませんが、実際にはバグがプログラマーに気付かれずにコンピューターのハードウェアに飛び込み、問題を引き起こしました。誰かが私を修正しようと思わないように、エジソンはmothの事件のずっと前にこの用語を使用したことを知っています。そのため、「起源」ではなく「歴史」という言葉を使用しました。computerworld.com/article/2515435/app-development/… および en.wikipedia.org/wiki/Software_bug#Etymology
threed

@threedもちろん。しかし、かなり長い間、昆虫はソフトウェアエラーの大部分を引き起こしていません。
リミスト

16
  1. テストを書きます。テストはバグの防止に優れているだけでなく(私の経験では、TDDを正しく行うことで、些細で愚かなバグをほぼすべて排除できます)、デバッグにも大いに役立ちます。テストにより、設計はかなりモジュール化され、問題の特定と複製がはるかに容易になります。また、環境を制御するので、驚きがはるかに少なくなります。さらに、失敗したテストケースを取得すると、気になる動作の本当の理由を明確に把握できます。

  2. デバッガーの使用方法を学びます。printステートメントはある程度のレベルで十分に機能しますが、ほとんどの場合デバッガーは非常に役立ちます(使用方法がわかれば、printステートメントよりもずっと快適です)。

  3. それが単なるゴム製のダッキーであっても、あなたの問題について誰かについて話してください。自分が取り組んでいる問題を言葉で表現することを強制することは、本当に奇跡を起こします。

  4. 時間制限を設けてください。たとえば、45分後にどこにも行かないと感じた場合は、しばらくの間他のタスクに切り替えてください。バグに戻ると、以前は考えもしなかった可能性のある他の解決策を見ることができます。


2
「自分が取り組んでいる問題を言葉で表現するように強制することは、本当に奇跡を起こします。」の+1
メリーランドマババー・ラーマン

(1)に追加するために、コードに表示されるほとんどすべてのバグは、テストスイートにバグがあること、または少なくとも漏れがあることを意味します。両方を同時に修正し、手元の問題を修正したことを証明するだけでなく、再導入されても安全です。
ジュリアヘイワード14年

3

バグの再現も重要だと思います。バグを再現するすべてのケースをリストし、バグ修正がそれらすべてのケースをカバーしていることを確認できます。


3

このテーマについて読んだ優れた本には、Why Programs Failがあります。これは、科学的手法を適用してバグを特定して解決することから、デルタデバッグに至るまで、バグを見つけるためのさまざまな戦略を概説しています。この本のもう1つの興味深い部分は、「バグ」という用語がなくなることです。Zellerのアプローチは次のとおりです。

(1)プログラマーがコードに欠陥を作成します。(2)欠陥は感染を引き起こします(3)感染は広がります(4)感染は失敗を引き起こします。

デバッグスキルを向上させる場合は、この本を強くお勧めします。

私自身の個人的な経験では、アプリケーションに多くのバグを発見しましたが、管理者は単に新しい機能を引き出すために私たちを先に押します。「このバグを自分で見つけたが、クライアントはまだ気づいていないので、気付くまでそのままにしておく」とよく耳にします。バグを積極的に修正するのではなく、事後対応することは非常に悪い考えだと思います悪循環に陥り、多大なストレスと燃え尽きを招き、最終的には欠陥のあるシステムになります。

バグが見つかった場合、コミュニケーションも別の要因です。電子メールを送信したり、バグトラッカーに文書化することは問題ありませんが、私自身の経験では、他の開発者は同様のバグを見つけ、コードを修正するためにあなたが置いたソリューションを再利用するのではなく)、独自のバージョンを追加するため、コードに5つの異なるソリューションがあり、結果として肥大化して混乱しているように見えます。そのため、バグを修正するときは、数人が修正をレビューし、同様の問題を修正し、対処するための優れた戦略を見つけた場合にフィードバックを提供するようにしてください。

limistは、バグの修正に関する興味深い資料が載っているThe Pragmatic Programmerという本に言及しました。前の段落で示した例を使用して、私はこれを見ていきます:Software Entrophy、ここでは壊れた未亡人のアナロジーが使用されています。2つの壊れたウィンドウが表示される場合、積極的な姿勢をとらない限り、チームはそれを修正することに無関心になる可能性があります。


「このバグを自分で発見し、クライアントはまだ気づいていないので、気付くまでそのままにしてください」と何度も聞きました。そして、サイト訪問に行って、多くの場合、クライアント気づきましたが、それを報告していません。修正されないので意味がないと思うこともあれば、競合他社の代替品をすでに見ていることもあるし、「(とにかく)ともかく、とにかくすべてががらくたの山だ」という理由もあります。
ジュリアヘイワード14年

@JuliaHayward-これは非常に頻繁に発生しますが、あなたの状況では、クライアントは機能に満足しており、内部で何が起こっているかをあまり気にしないかもしれません。クライアントが追加機能を求めて戻ってきたときに問題が表面化し始め、アプリを多言語でモバイルに準拠したものにするなど、別の拡張機能を追加する必要があります。あなたが持っているものを見て、壁のすべての亀裂を確認し始めます。
荒涼とした惑星14年

ソフトウェアの設計、テスト、優れたコミュニケーションに関する世界のすべての書籍と、取り組んでいる多くの製品は広大な混乱です。何が正しいのかを知っているにもかかわらず、ストレスと非現実的な期限(既に混乱しているコードに直面している)が、コードが現状のままである理由の背後にある理由です。自分には答えがありません。コードの健全性と開発プロセスをスムーズに保つためにキックと叫び声を上げている間、私はオフィスでうめき顔として非常に際立っていますが、チームは時々そうではありません」 tはよく結合します。
荒涼とした惑星

3

バグ、エラー、問題、欠陥-それを何と呼んでも、それほど違いはありません。それが私が慣れているので、私は問題に固執します。

  1. 問題の認識を理解します:「ボブはまだシステムにありません」から「ボブのユーザーレコードを作成しようとすると、重複キーの例外で失敗しますが、ボブはまだではありません」そこで'
  2. それが本当に問題なのか、それとも単なる誤解なのかを考えてみてください(実際、ボブはそこにいません。ボブと呼ばれる人はいないので、挿入は機能するはずです)。
  3. 問題を再現するために従うことができる最小限の信頼できる手順を取得してみてください-「ユーザーレコード「Buce」を持つシステムにユーザーレコード「Bob」が挿入されたときに例外が発生するなど」
  4. これはあなたのテストです-可能であれば、繰り返し実行できる自動化されたテストハーネスに入れてください。これはデバッグ時に非常に貴重です。また、テストスイートの一部として、特定の問題が後で再発しないようにすることもできます。
  5. デバッガーを取り出してブレークポイントを配置します-テストを実行するときにコードパスを把握し、何が問題なのかを特定します。その間、テストをできる限り狭くすることでテストを改良することもできます-理想的には単体テストです。
  6. 修正-テストに合格したことを確認します。
  7. 顧客が説明した元の問題も修正されていることを確認します(非常に重要-問題のサブセットを修正しただけかもしれません)。プログラムの他の側面に回帰を導入していないことを確認してください。

コードに精通している場合、または問題や修正が明らかな場合は、これらの手順の一部をスキップできます。

貴重な時間を最も有効に活用し、それを見つけようとする時間を短縮し、より多くの時間をコーディングできるようにするには、どのようにアプローチする必要がありますか?

新しいコードを書くことは、高品質の作業プログラムを持つことよりも価値があることを意味するので、私はそれを問題にします。問題を修正するのに可能な限り効果的であることには何の問題もありませんが、プログラムは単にコードを追加するだけでは必ずしも改善されません。


これがベストアンサーIMO
marcusshep

3

私は他のほとんどの答えが好きですが、ここであなたがそれをする前に何をすべきかのヒントをいくつか示します。あなたの時間を節約します。

  1. 本当にバグがあるかどうかを判断します。バグは常にシステムの動作と要件の違いです。テスターは、予想される動作と実際の動作を明確にすることができるはずです。期待される動作をサポートできない場合、要件はなく、バグもありません。誰かの意見です。返却してください。

  2. 予想される動作が間違っている可能性を考慮してください。これは、要件の誤った解釈が原因である可能性があります。また、要件自体の欠陥(詳細な要件とビジネス要件の差分)が原因である可能性もあります。これらも送り返すことができます。

  3. 問題を特定します。これを行う最も速い方法は、経験だけが教えてくれます。一部の人々は、ほとんど腸でそれを行うことができます。基本的なアプローチの1つは、他のすべてのことを一定に保ちながら1つのことを変えることです(問題は他の環境で発生しますか?他のブラウザーで?異なるテスト領域で?1日の異なる時間で?)別のアプローチはスタックダンプまたはエラーメッセージ-システムのどのコンポーネントが元のエラーをスローしたかをフォーマットする方法で伝えることができる場合があります(たとえば、ドイツ語の場合は、ベルリンで作業しているサードパーティのせいにすることができます)。

  4. 連携する2つのシステムに絞り込んだ場合は、トラフィックモニターまたはログファイルを介して2つのシステム間のメッセージを検査し、どのシステムが仕様どおりに動作し、どのシステムがそうでないかを判断します。シナリオに3つ以上のシステムがある場合は、ペアワイズチェックを実行して、アプリケーションスタックを「ダウン」することができます。

  5. 問題の切り分けが非常に重要である理由は、問題はあなたが管理しているコードの欠陥(たとえば、サードパーティシステムまたは環境)によるものではない可能性があり、そのパーティにできるだけ早く引き継がせたいからです。 。これは、作業を節約すると同時に、できるだけ短時間で解決できるようにするためです。他の人のWebサービスの問題であることに気付くためだけに、10日間問題に取り組みたくありません。

  6. 本当に欠陥があり、実際に制御するコードにあると判断した場合、最後の「既知の正常な」ビルドを探し、問題を引き起こした可能性のある変更についてソース管理ログを調べることで、問題をさらに分離できます。これにより多くの時間を節約できます。

  7. ソース管理から理解できない場合は、今すぐデバッガを接続し、コードをステップ実行して理解してください。とにかく、問題についてかなり良い考えを持っている可能性があります。

バグがどこにあり、修正を考えることができると、それを修正するための良い手順があります:

  1. 問題を再現して失敗する単体テストを作成します。

  2. 単体テストを変更せずに、(アプリケーションコードを変更して)合格します。

  3. 回帰を防ぐ/検出するために、テストスイートで単体テストを保持します。


1

以下にその方法を示します。

  1. 毎回同じ方法を使用して問題を見つけてください。これにより、エラーに対する反応時間が改善されます。
  2. 最善の方法は、おそらくコードを読むことです。これは、すべての情報がコードで利用可能であるためです。正しい位置を見つける効率的な方法と、すべての詳細を理解する能力が必要です。
  3. デバッグは非常に遅い方法であり、プログラマーがコンピューターがasm命令を実行する方法をまだ理解していない/コールスタックや基本的なものを理解できない場合にのみ必要です
  4. 関数のプロトタイプを使用してプログラムの動作を推論するなどの証明技術を開発してください。これにより、正しい位置をより速く見つけることができます

1

コードでエラーを検出した場合、それを取り除くために何ができますか?貴重な時間を最も有効に活用し、それを見つけようとする時間を短縮し、より多くの時間をコーディングできるようにするには、どのようにアプローチする必要がありますか?また、デバッグするときは何を避けるべきですか?

実稼働環境にいると仮定すると、次のことを行う必要があります。

  1. 「エラー」を正しく説明し、それを引き起こすイベントを特定します。

  2. 「エラー」がコードエラーか仕様エラーかを判断します。たとえば、1文字の名前を入力すると、一部のシステムではエラーと見なされますが、他のシステムでは許容される動作です。ユーザーが問題だと思うエラーを報告することもありますが、システムの動作に対するユーザーの期待は要件の一部ではありませんでした。

  3. エラーが存在し、そのエラーがコードによるものであることが判明した場合、エラーを防ぐために修正する必要のあるコード部分を判別できます。また、現在のデータおよび将来のシステム操作に対する動作の影響を調べます(コードおよびデータへの影響分析)。

  4. この時点で、おそらくバグを修正するためにどれだけのリソースが消費されるかを見積もるでしょう。すぐに修正するか、ソフトウェアの今後のリリースで修正をスケジュールすることができます。これは、エンドユーザーが修正に対して支払う意思があるかどうかにも依存します。また、使用可能なさまざまなオプションを評価して、エラーを修正する必要があります。複数の方法があります。状況に最適なアプローチを選択する必要があります。

  5. このバグが発生する原因(要件、コーディング、テストなど)を分析します。条件の再発を防ぐプロセスを実施します。

  6. エピソードを適切に文書化します。

  7. 修正(または新しいバージョン)をリリースします

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