デバッガーの使用を避ける利点は何ですか?


101

私のキャリアの過程で、一部の開発者はデバッグツールを使用しないことに気付きましたが、問題が何であるかを把握するために誤ったコードをチェックします。

多くの場合、デバッガーなしでコード内のエラーをすばやく見つけることができるのは良いスキルですが、デバッガーがタイプミスなどの小さな間違いを簡単に見つける場合、問題を探すのに多くの時間を費やすことは生産性が低いようです。

デバッガなしで複合システムを管理することは可能ですか?お勧めですか?「サイキックデバッギング」を使用することで得られるメリットは何ですか?


19
こんにちはジョナサン、私はあなたの質問を修正して、暴言のわなを避け、質問を開いたままにします。私は-今言われているように-それはまともな、答えられる質問だと思います。

例:a = 6/3入力したタイプミスの代わりにコードを検討してくださいa = 6/2..ニーモニックレベルで検索し、ADD、JMP命令を実行すると、2の代わりに1つの反復が追加されたことがわかります。間違ったタイプミス。これで、常にデバッガを使用するのがどれほどばかげているかを推測できます。
EAGER_STUDENT

回答:


153

外部から推測するように見えるものは、しばしば私が「あなたの心の中でデバッグする」と呼ぶものであることが判明します。ある意味では、これは、チェス盤を見ずにチェスをするグランドマスターの能力に似ています。

それははるかにそれがすべてでデバッガを必要としないので、私が知っている最も効率的なデバッグ手法。脳は同時に複数のコードパスを探索し、デバッガーで得られる可能性よりも優れたターンアラウンドをもたらします。

競合するプログラミングの世界に入る前に、私はこの手法について意識していませんでした。約1年の競争の後、私はこの手法を最初の防御線としてほぼ独占的に使用し始め、その後デバッグロギングを行い、実際のデバッガーを3位に配置しました。このプラクティスの有用な副作用の1つは、新しいコードを書いたときに「頭の中のデバッグ」が止まらないため、新しいバグをゆっくりと追加し始めたことです。

もちろん、この方法には制限があります。これは、主に、コードの複数のパスを視覚化する際の心の制限によるものです。私は心のこれらの制限を尊重することを学び、より高度なアルゴリズムのバグを修正するためのデバッガーに目を向けました。


27
+1「推測によるプログラミング」がロードされたフレーズであることがわかりました。思考に代わるものはありません。OPが説明していないのは、「推測」がどれほど効果的かということです。私の疑いは、それが純粋に推測しているということです(つまり、壁にスパゲッティアプローチ)、むしろ演ductive的推論を使用しています。デバッガーには場所がありますが、演ductive的推論や単にコードを理解するための万能薬ではありません。
ビル

8
@DJClayworthそれは完全に正確ではありません:デバッガーを自由に使用できる場合でも、デバッガーを使用しようとするのは適切ではない場合があります。すぐに頭に浮かぶ1つのケースは、同時実行の問題を解決することです。もう1つは、分岐係数の高い再帰アルゴリズム、いくつかの動的プログラミングアルゴリズム、およびハードウェア割り込みサービスルーチンのデバッグです。もちろん、本当に必要なときにデバッガーを使用しないのはばかげていますが、いつデバッガーが必要になるかを決めるのは非常に個人的な選択です。
-dasblinkenlight

9
1私は実際にコードの単純良好な理解のための代替はありません(特に、より複雑なアルゴリズムで)バグの特定の種類のための貴重なデバッガを見つけることが
クリス・ブラウン

7
@DJClayworth私は意図的に「デバッガーを使用しないときのほうが良い」よりも強力なステートメントを求めました:競合プログラミングとの短い出会いは、本能的にデバッガーに到達することは私にとって最も効率的な行動はないことを教えてくれました。最近では、(1)コードをすばやく再読み込みし、(2)デバッグトレース(利用可能な場合)を調べてから(3)デバッガーに行くことから始めます。多くの場合、3番目のステップは不要です。ステップ(1)または(2)で問題を見つけ、問題を再現する単体テストを作成し、修正プログラムをコーディングします。すべてデバッガーを使用しません。
-dasblinkenlight

10
あなたが本当に言っているのは、プログラマーが魔法の「バグを見つける」ボタンをクリックする代わりに、デバッグシーケンスを用意するべきだということだと思います。デバッガーは非常に強力なツールですが、チェーンソーを起動してヘッジをトリミングすることはありません。
スペンサー

41

コードベースを理解すればするほど、デバッガーは必要なくなります(ただし、報告されたエラーを引き続きチェックします。これはあらゆる推論の重要な手がかりです)。

小規模から中程度の複雑さのいくつかの動的な動作を理解するための優れたツールですが、私はしばしば、全体像ではなく詳細に焦点を当てていることに気付きます。そしてしばらくすると、そこに問題があります:動的な動作が他のツール(たとえば、モジュール境界での入力と出力のロギング)でより簡単に理解される傾向がある広い範囲の相互作用。


35

彼らは悪いプログラマーではないかもしれませんが、恐らくひどく非効率的なトラブルシューティングです。

私はデバッグからのアドバイスに従う傾向があります:最もとらえどころのないソフトウェアとハ​​ードウェアの問題を見つけるための9つの不可欠なルール(David Agans)。


12
私は同意しませんが、私は反対票を投じません。delnanが言うように、コードが何をしているのかを理解できれば、デバッガーをステップスルーし、エラーが発生したときに見つけることを試みるよりも、コードが間違っていることを見つける方が速くなる可能性があります。そうは言って、コードの読み取りから問題を特定できないときにデバッガーの使用を拒否する開発者は、大きな間違いを犯しています。

@Markに加えて、問題の誤診と新しい欠陥のプラグインの追加ボーナス。
キースは

11
@マークバニスター-あなたの言っていることがわかります。コードの問題を15分以上探している場合は、デバッガをあきらめて使用してください。頑固にならないでください。
JohnFx

9
優れたプログラマーはデバッガーに依存すべきではないと思います。...または定期的に、彼の洞察力がトラックに残っていることを確認する-これは彼の洞察力が失敗したら(利用可能な場合)、すぐに1を使用してから彼を保つべきではない
comingstorm

1
@markは、非常に小さなコードベースで作業している場合を除き、すべてのコード行を理解することは不可能だと思います。私の現在のバグの95%は、あなたが説明した方法で解決されますが、より厄介なバグは、デバッガが必要な場所です。
wobbily_col 14

31

どんな仕事でも、正しいツールを正しい方法で使用する必要があります。デバッガがある場合は、それを使用して実際に何が起こっているのかを確認します。ほとんどのバグは仮定によって引き起こされます。

デバッガーの方がよく知っているため、デバッガーの使用を拒否する開発者と協力しました。かつて私が得た古典的な応答は、「クラッシュは私に起因するものではなく、1日中コードを調べて(クラッシュしているところに)何の問題もない」というものでした。(dbから読み込まれたnull値についてはどうでしょうか?)上司はそれはすばらしい返信だと思ったようですが、顧客はそうしませんでした。

私はできるだけ早くそのチームを降りました。彼らの目的は、仕事を絞り込み、10分間の単純な問題を終日見かけの忙しい問題にすることでした。


18
+1「ほとんどのバグは仮定によって引き起こされる」は非常に賢明な言葉です
-ZJR

15
私はすべてのバグが仮定に起因すると仮定します。(私がそこで何をしたかを参照してください= P)
dan_waterworth

4
@ZJR:だからこそassert、こんなに素晴らしいのです。前提を確認してください。頻繁に確認してください。
ザンリンクス

@dan_waterworth:違います。1つは、タイプミスの可能性があります。
トーマスエディング

13

デバッグの実践に関する最良のガイドは、Steve McConnelの本Code Completeです。第23章ではデバッグの詳細について説明しますが、ここからいくつかのポイントを抽出します。

  1. 問題を理解することは重要であり、デバッガーの使用はそれに代わるものではありません。
  2. 推測はデバッグへの悪いアプローチです。同僚が問題について考えるのではなく、実際に当て推量を使用している場合、彼らは悪い仕事をしています。推測とは、コードにランダムな印刷ステートメントを貼り付け、有用なものを見つけたいということです。
  3. 同僚が(デバッガを使用しないことを選択するのではなく)デバッガの使用方法を本当に知らない場合、はい、彼らは使用するはずの言語の構文を知らない人のように無能です。

2
私はあなたの投稿の大部分であなたに同意しますが、無能は不公平だと思います。デバッガを使用せずに開発することは可能ですが、非効率的です。デバッガーについて他の人よりも先に学ぶ人もいます!
クリスフレッチャー

私は「無能」のような言葉を何気なく投げつけません。印刷文を使用して完全にデバッグする人を知っていますが、彼が貢献することに誰も近づいていません。
マイクダンラベイ

2
@MikeDunlaveyその人はデバッガの使用方法を知っており、デバッガを使用しないことを選択していますか?いいよ 彼らが知らない場合、私は私の声明を支持します。
DJClayworth

2
好きなように立ち、その形容詞があなたに適用されるかもしれない時が簡単に来るかもしれません。理解できます-それは校庭のものです。
マイクダンラベイ

9

わかりにくい。推測によるデバッグかもしれないあなたはすでにバグが(ライブラリ関数に渡された不正な値、おそらく無効なSQLなど)であるかについてのアイデアを持っている場合は動作します。「文字バッファが小さすぎる」など、エラー自体が小さいか明らかな場合に時々それを行うことを認めています-スタックトレースは失敗した行を表示し、それを解決するためにデバッガを必要としません。

常にこれを行うと逆効果になる可能性があり、最初のいくつかの「推測」が失敗した場合、推測はおそらく間違った問題解決戦略であり、実際のデバッガーを呼び出す必要があります。 。

そうは言っても、デバッガを正しく動作させるのが非常に難しいツールや環境で作業したか、または非常に最小限で役に立たないので、残念ながら推測がより良いアプローチでした。適切なデバッガーさえも持たない独自のツールをいくつか使用しました。そのような環境で長時間働いている人は、デバッガーに対する信頼を失い、推測アプローチに頼る可能性があると思います。


8

このトピックに関する議論で「ユニットテスト」が言及されていないことに驚いています。

私はテスト駆動開発を行っているため、デバッガーで多くの時間を費やすことはありません。10年前、私は忠実にデバッガーをステップスルーしていました。

  1. 動作することを確認するためにコードを書いた後、
  2. 問題を診断しようとするバグレポートを受け取ったとき

10年間のテスト駆動開発の後、私が見つけたのは、次の場合にプログラマとしての生産性が大幅に向上したことです。

  1. コードを書くにユニットテストを書いて、正しく書いたことを確認します
  2. バグレポートを受け取ったらすぐにユニットテストを書いて、問題の再現とドリルダウンを試みます。

コンピューターがコードを実行して結果を検証できるようにすることは、コードを考えたり実行したりして結果を精神的に検証するよりも何千倍も速く、間違いを犯しません。

ときどきデバッガーをステップスルーする必要があり、コードのメンタル分析に引き続き取り組んでいます...


+1多くの場合、printステートメントを追加してテストを再実行し、デバッガーを使用する方が高速です。
ウィンストンイーバート

@ winston-問題のあるコードの場所が見つかるまで、複数のprintステートメントを書くよりもデバッガを起動する方が速いことがよくあります。それはすべて依存しています。通常、単純な問題は記述した方法でより迅速に解決されますが、デバッガーが必要なのは複雑な問題です。両方を使用できることは、絶対的な原則に厳密に従うことよりも優れています。
wobbily_col 14

7

個人的には、次の方法でデバッガーの使用を最小限に抑えようとしています。

  • 使用して静的チェッカーコードだけを解析することで、バグの可能性のあるソースを示唆し、同様のコンパイラオプションを
  • 可能な限り最も機能的なスタイルで、可能な限り少ない副作用でコードを記述し、可能な場合は変更可能な状態を排除する
  • 最小限の合理的な粒度で単体テストを書く
  • 例外を飲み込まない

もちろん、誰もがエラーを発生させるため、この方法でプログラムを作成する場合でも、テストが失敗した場合、デバッガーを使用して中間式の値を検査します。しかし、上記の原則を順守することで、欠陥を見つけやすくなり、デバッグは痛みを伴う不確定なプロセスを意味しません。


6

可能な限りデバッガーを使用してください。デバッガは単に問題を特定するか(この値を確認しませんでした)、または関連するコードを分析するときに役立つコンテキストを大量に提供します(すごい、スタックが完全に台無しになります。バッファオーバーフローの問題です)。


5

デバッグは、実行時にコード内のオブジェクトと変数の状態を検査するための非常に便利なツールです。

上記の回答で前述したように、デバッグは非常に役立ちますが、制限される場合があります。

私の経験では、デバッガーを使用すると、コードの状態について行っていた誤った仮定を明らかにするのに役立つため、非常に便利です。一部の人々はバグを見つけるためにコードを読み通すことに鋭敏ではないので、デバッグはコードの状態についてあなたや他の開発者が行った誤った仮定を明らかにするのに役立ちます。

メソッドに渡されたときにパラメーターがnullにならないことを期待している可能性があるため、そのケースをチェックせず、そのパラメーターがnullにならないかのようにメソッドを続行しません。現実には、パラメーター nullであってはならないという前提条件としてメソッドを設定した場合でも、ある時点でパラメーターがnullになることがあります。それは常に起こります。

前述の例でのデバッガーの有用性とは対照的に、マルチスレッド(つまり、並行処理、非同期処理)が関係する場合、使用するのは難しく、やや役に立たないことがわかります。これは役立ちますが、デバッガーのブレークポイントがポイントAの1つのスレッドとポイントBの完全に別のスレッドでヒットしている場合、マルチスレッドフォグで方向を失うのは簡単です。開発者は新しいブレークポイントをプッシュするように強制されます思考プロセス」を脳の「スタック」の上に配置し、新しいブレークポイントのポイントでコードの方向を決めます。ブレークポイントBの関連性が低下すると、開発者は最初のブレークポイントに戻り、ブレークポイントBのトリガーの前に探していたものを思い出す必要があります。これは混乱を招く説明かもしれませんが、

また、並行コードの予測不能性は、並行コードのデバッグにおいて開発者の注意をさらにそらします。

結論として、私の正直な意見では:

  • 並行性が使用されている場合のデバッグ=「思考パターンのデバッグ」の焦点を失う傾向の増加

そして

  • いつでも=デバッグの生産性を向上b / c予期しないブレークポイント(競合状態により予期しない)によって注意が中断されない。

2
+1は、従来のデバッガーの有用性がほとんどゼロにまで低下する、並行環境でのデバッグの問題を提起するためのものです。
-dasblinkenlight

4

ちょっとハードコアすぎると思う。個人的にバグに遭遇したとき、コードを再確認し、プログラムロジックから心の中でトレースしようとします。 。

打ち込んだと思っても、通常はデバッグして自分が正しいことを確認します。問題がもう少し複雑な場合、デバッグは絶対に不可欠だと思います。

また...私の意見だけですが、現代のIDEがテーブルにもたらすことができるツールを十分に活用しない理由はありません。それがあなたの仕事をより速く、より信頼できる方法で完了するのを助けるなら、あなたはそれを使うべきです。


4

一般化するのは嫌いですが、私が会った多くのプログラマーは、問題を解決する方法は1つしかないと考えています(その方法)。考えられるすべてのテストが考えられていると推測するのは簡単です。別の視点は非常に価値があります。

試行錯誤によるプログラミングは、いくつかの素晴らしい新しいアプローチを思い付くことができ、他の人が見逃したものをキャッチできます。

欠点は、通常はるかに時間がかかります。


4

えーと、それは人次第です。個人的には、私はあまりデバッガーを使用していません。マイクロコントローラーをプログラムするときは、基本的にLEDを使用するか、EEPROMにデータを書き込んでコードを「デバッグ」します。JTAGを使用しません。

PCまたはサーバー用のソフトウェアをプログラムするとき、ロギングと多くのコンソール出力を使用する傾向があります。Cスタイル言語では、プリプロセッサディレクティブを使用し、Javaではログレベルを使用しました。

デバッガーを使用していないので、何か間違ったことをしていると言いますか?構文エラーがどこにあるかを示すのはエディターの仕事であり、論理エラーがある場合はテストを実行するだけです。


4

デバッガを使用する必要がないことと、デバッガの使用方法(または拒否)を知らないことには違いがあります。デバッガは、バグの追跡と修正に使用する多くのツールの1つにすぎません。私は頭の中でそれを解くことができる開発者と、彼らができると思う他の人と仕事をしました。

最適な組み合わせは、ユニットテストで簡単にテストできるようにコードを記述し、エラーをログに記録することです。次に、ログを確認したり、デバッガを使用したりする必要がないことを望みます。保険を買うようなものです。あなたはそれを使う必要がないことを願っていますが、コードを再チェックしても解決できないバグに出くわすと、適切なエラー処理/ロギング、単体テストを追加したり、デバッガーの使用方法を習得するには遅すぎます。

さまざまなツール/プラットフォームは、さまざまなデバッグ手法(デバッガー、ロギング、単体テストなど)を好みます。開発者がプラットフォーム/ツールの手法のいくつかに精通している限り、コードの再確認だけでなく、熟練した開発者ですが、デバッグに関して1つのトリックしかない場合、最終的には発見も修正もできないバグに遭遇します。


4

多くの答えがありますが、ハイゼンバグについては言及していませんか?!?!

ハイゼンバグが発生するのは、出力ステートメントの挿入やデバッガーでの実行など、プログラムをデバッグする一般的な試みが通常コードを変更し、変数のメモリアドレスとその実行のタイミングを変更するためです。

デバッガーを使用するのは、最悪の場合のみ(見つけにくいバグの場合)。また、多くの称賛されている開発者/テスターが話しているベストプラクティスに従って、コードを徹底的に単体テストすることは良いことです。そうすれば、ほとんどの問題をカバーできるため、デバッガーを使用する必要はありません。


3

最近、ここでデバッガのデバッグに対する議論を読みました(またはStackOverflowでしたか?)。コードに対してテストケースを作成する必要があります。テストに合格した場合、おそらくデバッグではバグが発生しません(仮定:テストデータに似たデータを使用してデバッグします)。

一方、ロギングは必須です。テストに合格して本番環境にデプロイすると、バグがあることがわかります。バグの証拠は、過去に発生した何かからのものです。すなわち、誰かが「どうやってそこに入ったの?」と言う。適切なログがない場合、原因を見つけることはできません。デバッガーでさえ、その時点では役に立たないかもしれません。なぜなら、実際にバグを実行したデータがどのように見えたのかわからないからです。ログからアプリケーションをデバッグできる必要があります。

残念なことに、私はかなり言い換えているので、元の議論を傷つけているかもしれません。特に、「開発時間のサポートに費やす重要なデバッグ支援者がいる」という立場は、デバッガの重要性とは正反対かもしれません。しかし、デバッグでバグを見つけるのに役立つ構成でシステム状態を設定することの難しさに関する部分は、私が考えることとして思いました。


3

優れた単体テストと、バックトレースを提供する例外により、デバッガーを使用する必要はほとんどありません。

デバッグを最後に使用したのは、レガシーアプリケーションでコアファイルを取得したときでした。

私は「デバッガーミニオン」なのか、それとも「ハードコアすぎる」のか。

どちらでもない。彼らは人生をもっと難しくするのが好きな人のようなものです。


2

デバッグは、優れた開発者が上手に使用すべきツールにすぎません。

確かに、コードベースを知っていれば、バグがどこにあるかを心から知ることができます。しかし、コードを調べるだけで、厄介なバグを見つけるために1日または1週間も失う可能性があります。

何らかのデバッグなしの動的型付け言語では(コンソールに値を単にダンプする場合でも)、推測が不可能になることがあります。

あなたの質問に答えるために-多分彼らは優秀なプログラマーかもしれませんが、彼らのトラブルシューティングのスキルとバグを捜すときの熟練は悪いです。


2

問題の範囲に依存します。プログラムが小さく、物事がうまく分割されている場合は、見ればわかるでしょう。プログラムが数年かけて100人以上のチームによって開発された450万行のコードである場合、特定のバグを見つけることは不可能です。

上記のプログラム(C)で問題となっているのは、メモリの上書きです。メモリブレークポイントを持つデバッガーは、バグが発生するとすぐに問題のあるコード行を特定しました。しかし、この場合、450万行すべてのコードを読み取って保持し、誰かが自分の配列を超えて書き込んだ1つのスポットを識別する方法はありません(さらに、巨大なプログラムの状態のメモリのランタイムレイアウトを知っている必要があります)そのポイントに到達するための入力の長い実行に約10分かかります)。

要点:小さなプログラムまたは高度にモジュール化されたものでは、デバッガなしで逃げることができます。プログラムが本当に大きく複雑な場合、デバッガーは多くの時間を節約できます。他の人が言ったように、それはツールであり、他のどの方法よりも優れている状況と、最良の選択ではない状況があります。


0

バグがクライアントのコンピューターで発生する場合、またはその環境がユーザーの環境と大きく異なるコンピューターで発生する場合、デバッガー/リモートデバッガーのセットアップは面倒です。そのため、フィールドからバグを取得する寒い日には、「しかし...デバッガがありません」という応答は役に立ちません。したがって、コードとログファイルを理解するだけで、トラブルシューティングのスキルセットを開発し、バグを見つける必要があります。


-1

「実在のプログラマーはデバッガーを必要としません。」実際のプログラマーはIDEを必要としないと言うかもしれません。メモ帳と鈍い鉛筆をください。デバッガは、生産性を高める他のツールと同様のツールです。

また、コードのデバッグを担当する全員が問題のコードに精通しているわけではないことを考慮してください。多くの時間請負業者は、何が起こっているのかという一般的な理想しか持っていない環境になります。環境の詳細な説明、または20年前のスキーママップと難解な命名規則のガイドが提供される場合もあります(フィールドF1、F2、F3を持つテーブルX1234とテーブルX4312の違いを理解してみてください[はい、このようなゴミ存在する]が新しい場合)、しかし、その記述はしばしば間違っています。そうでなければ、なぜ「ミステリー」エラーがあるのでしょうか。

環境に不慣れな人は、修正する可能性のある問題領域を大規模なデータベースにマッピングして「知る」ために何時間も何日も費やすことができます。これは時間とお金の大きな無駄です。デバッガーにアクセスできる場合、何が起こっているのかを確認して修正し、数分で消えます。この「デバッガーは必要ありません」すべては、エリート主義者の苦悩に過ぎません。


2
このストローマンの暴言は、「本物のプログラマはデバッガを必要としない」という声明はどこにもありません
-gnat
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.