既存のコードをデバッグする能力を向上させる方法[終了]


29

ワーキングワールドでの一般的なタスクは、既存のバグのあるコードの処理です。デバッガーとしてのスキルを向上させるためのヒントは何ですか?



2
元の著者に回答を求めてウォーターボードします。
ジョブ

回答:


32

何も想定しない

「ああ、私はこのコードが何をしているのか知っている、それでいい」と言うのは魅力的です。しないでください。すべての仮定をテストし、すべてを慎重にステップスルーします。


2
+1。絶対に。あなたが知っていると思っていたもののいくつかがあなたにトリックをかけることになることに驚かされる準備をしてください。
aufather

私のために働く:)
setzamora

3
他のコードのデバッグは時間の浪費であり、生産性を損なうものですが、それはそうです。他のバグを修正することが本当に理にかなっているのは、彼らが去ったときだけです。嫌いなこと嫌いな人は、上級コーダーが客観的にくだらないコードを調べ、タイムリーに進歩するために質問をしなければならず、既存のコードベースを学ぶスキルを向上させるための講義を受けます。母なる自然を研究するのとは異なり、人間に起因するねじ込みを解決することはほとんど楽しいことではありません。少なくとも、答えが得られます。逆の状況は発生しません。なぜなら私はより良くなり、バグが少なくなるからです。
ジョブ

1
@ジョブ:...大丈夫ですか?おそらく、このコメントを投稿に残すつもりでしたか?:)
アダムリア

この!奇妙な問題をデバッグしていて、コードが正常に見える場合、コードの小さな部分を盲目的に信頼するのはばかげています。
ダン

7

段階的にテストします

コードの深さを最初に調べ、徐々に上に移動する最小のモジュールからテストします。このようにして、問題がどこにあるのかを正確に把握しようとしても、あまりストレスがかかりません。

それはまた、あなたが少しずつ動いているので、一度に少ないコードに影響することを意味します。私が混乱したときに彼がこれを教えてくれたので、私はこれを上司に信用します。


4

分割統治は良いアプローチです。問題が存在する、目に見える入力(ユーザー入力/ネットワークイベント...)と出力(ログ、ユーザーへの出力、送信ネットワークメッセージ...)を特定してください。サイズの大きいチャンクまたはそれらの間の重要なポイントにプリントを配置して、コード内のバグの場所を絞り込みます。

分割統治は、バージョン管理されたコードの回帰の場合にも非常にうまく機能します。2つのビルドを見つけます-1つは期待どおりに機能するビルド、もう1つはリグレッションでビルドします。潜在的な容疑者として多数のチェックインが残るまで、ギャップを狭めてください。


4

バイナリバグチョップではなく、フォームにテストを記述します

  • 与えられた...
  • いつ...
  • 期待する...

アプリの機能について実際に真実であるとわかっていることと、真実であると仮定していることを確認するため。

ほとんどのIDEでは、メソッドの抽出とxUnitテストスタブの生成が簡単になります。それを利用してください。

デバッグを振りかけませんか?完了したら、その作業の多くを元に戻して、かなりの量のデバッグを削除する必要がある可能性が高いためです。テストを書くとき、デバッグは将来のバグの予防と検出に役立ちます。


2

デバッグを続けます。たくさんデバッグすれば、改善できます。


デバッグはそれ自体が芸術であり、特に他の人々のコードのデバッグです。
Gratzy

2

他の人が言ったように-何も仮定しないでください。これは、コードを記述した場合に特に当てはまります。他のコードをデバッグする場合、コードが初めての場合やコーダーを信頼していないため、速度が低下する可能性が高くなります。あなた自身のコードをデバッグするとき、あなたがそれを正しく書いたと仮定するのは簡単すぎるので、遅くしてください!

デバッグの実際のプロセスの場合:

  • ユニットテストが存在しない場合は作成します。
  • まだ存在しない場合は、適切なログを追加します。
  • 次に、デバッグを使用します。

最初にデバッガーを使用するよりも、ユニットテストとログを最初に追加する方が効率的です。また、単体テストを使用して将来のバグを発生させないという追加の利点が得られ、ロギングは将来のセッションのデバッグに役立ちます。


1

コードの小さなチャンクをステップオーバーする前に、結果を正確に判断できるかどうかを確認してください。これは何も仮定しないことで飛ぶ傾向がありますが(私はBTWに賛成票を投じました)、経験を積むにつれて、どこを見るかを絞り込むのに役立ちます。

これは些細に聞こえるかもしれませんが、デバッガのニュアンスとホットキーを学びます。デバッガーの速度が遅いため、ステップ実行時に頭が不思議に思うことがあります。マシンに遅れずについていくことができ、マウスを動かしていない場合は、それが役立ちます。

デバッグ中にコードを変更できる場合:

  • 事前条件と事後条件のアサートを検討してください。場合によっては、コードではなくステップオーバーできます。
  • 複雑な表現を含むifステートメントについては、何かを検討してください(一部の人はこれに眉をひそめるかもしれませんが、それは私には有効です)

のような:

bool isLessThan5 = a < 5;
bool isGreaterThan10 = a > 10;
if ( isLessThan5 || isGreaterThan10 )
{
   // more code here
}

の代わりに:

if ( a < 5 || a > 10 )
{
   // more code here
}

何らかの理由で、すべてをデバッグできない場合は、同僚と「ゴムダック」することを学んでください。時には説明する行為が光を放ちます。(わかりました、これは質問のテーマに正確に当てはまらないかもしれませんが、言及するのに十分であると思います)


1
サブ条件の命名には、さらに条件が必要です。つまり、条件の目的がわかったときに名前をリファクタリングする必要があります。if (tooCloseToHydrant || overTheBrink) { 後でさらに学習するときに判明する場合があります。

1

過去22年間の大半を他の人が書いたコードの保守に費やしたことに基づく2つのこと。

書く傾向があるバグの種類を理解する。

たとえば、私は非常に細心のコーダーなので、コードがコンパイルされると、通常は些細なバグがなくなります。したがって、私のバグは、スレッドのデッドロックのような奇妙で複雑なものになる傾向があります。反対に、ほとんどの些細なバグを書いている友人がいます。C++ forループの最後にセミコロンがあります。そのため、次の行は一度だけ実行されます。

他の人があなたと同じ種類のバグを書いていると思い込まないでください。

バグが私の一種の非常に微妙な奇妙なものであると仮定して、大きなデバッグ銃を引き出すのに時間を無駄にしたことが何回あるかわかりません。セミコロン?" その数年後、私はまず、他の人のコードを見るときに、ささいな、ささいな果物を探しに行きます。


何か動きがあるかどうかを確認するためにコードを再フォーマットしますか?

@Thorbjørn:コードの所有権を取得した場合、読みやすさを改善するためにそれを行うことがありますが、タイプミスを見つけるためではありません。面白いアイデア!
ボブマーフィー

コミットする必要はありません。何が起こるかを見てください。チェックイン時に、コードの再フォーマットを必要とする

@Thorbjørn:それをやりたいです。コード「prettifier」として何をお勧めしますか?私は主にLinuxとMacで仕事をしています。
ボブマーフィー

私は両方の場所で利用可能なEclipseを使用します。Javaエディターには、ファイルを保存するたびに何を実行するかを指定できる、いわゆるSaveアクションがあります。ここで、オプションの1つはソースのフォーマットです。私たちは小さなチームですので、私はそれについて詳しく調べていません。より経験豊富なチームは、ソース管理システムでコミット前のフックを許可し、ソースのコミットが正しくフォーマットされていない場合に拒否されるようにします。非常に効率的です。

1

ツールを知ってください。たとえば、Visual Studioのデバッガーには、ブレークポイントのようなTracePointsと呼ばれるすばらしい機能がありますが、コードを停止する代わりに、デバッグ出力にトレースステートメントを挿入します。

デバッガーの使用方法に関する本を読んだり、クラスを受講することを強くお勧めします。いくつかのクラスを受講し、デバッガーとしての私の有効性に大きな違いをもたらしたJohn Robbinsの本をいくつか読みました。


0

コードが何をしようとしているかを機能的に理解します。全体像がわからない場合(このコードに合格する必要があるすべてのテストケース)、新しいバグを導入せずに適切にデバッグすることは困難です。


0

自動化された単体テストとその他の種類の統合および機能テストを作成します。

自動化されたテストが多いほど、デバッガで費やす時間が短くなります。

また、優れたデザイン-固い原則。小さく焦点を絞ったクラスを作成し、継承よりも合成を優先し、重複を排除するなどの場合、コードは常にデバッグしやすくなります。

うまく設計されたコードは、うまく設計されていないコードとは異なる一連のバグを生成することがわかります。一般的に、適切に設計されたコードは、見つけやすく、再現しやすく、修正しやすいバグを生成します。

例外(常に1つあります)はマルチスレッドコードです:-)


0

それを小さな領域に絞り込んでも、まだエラーを見つけられない場合は、デバッガの「コードを表示+アセンブリ」オプションを試してください。「ここにブランチがあるはずです」または「なぜ低い単語をコピーするだけなのか」と言うのに十分なASMを知っている。多くの場合、コーディングエラーを特定します。


0

Andreas Zellerによる非常に貴重な本「プログラムが失敗する理由:体系的なデバッグのガイド」をご覧ください。多くの技術、理論、ツールを紹介します。そのうちのいくつかは最先端の研究です。

この本のスライドはオンラインで入手できますが、本自体は読みやすいと思います。

この本は、デバッグを開始するのに役立ち、デバッグについてより科学的に考えるのに役立ちますが、実践に代わるものではありません。パフォーマンスの大幅な改善が見られるまで、10年間の記述とデバッグが必要になる場合があります。私は、30年にわたってUnix向けのプログラミングを行ってきたシニア開発者が、数分であいまいなマルチスレッドまたは並列バグを見つけるのをSunに驚かせたことを今でも覚えています。経験が重要です!


自動化されたソフトウェアは非常に興味深いようです。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.