私はジュニアプログラマー(これまでの4か月のキャリア経験)で、クロスプラットフォームモバイルアプリケーション(1人のチーム-自分自身)に取り組んでいます。
このプログラム/アプリにはかなり大きなバグがあります(30の異なるヘッダーファイル、それぞれ独自のcppファイルも含まれます)。私はバグで何が起こっているのか正確に追跡し、それを修正しようとしています(いくつかのハックを使用してそれを機能させるだけでも試みました)が約12以上の解決策(問題を引き起こしているものがあると考えているので) )私は何も考え出さず、バグが何であるかを正確に追跡したり、バグを修正したりしました。
いくつかの幅広いテクニックのジュニアプログラマーにアドバイスはありますか(実行に行き、すべてのコードを紙に印刷し、ペンでそれを通過するなど)このバグの支援に使用できますか?
私のバグにもう少しコンテキストを与えるために;これにはクロスプラットフォームAPI Mosyncが含まれます。特定の一連のアクションを実行しても、現在の画面は再描画されません(そして表示されます)。
特定のシーケンス:
-メニュー画面が表示されます-[前の注文を表示]ボタンをクリックします
-前の注文画面が表示されます-[ファイルをロード]をクリックしてから、メニューボタンをクリックして配信画面を開きます
-配信画面が表示されます-メニューボタンをクリックして、購入画面を開きます
-購入画面が表示されます-ここでエラーが発生し、この画面への入力が表示されない/反応しない、リストビューがスクロールしない、ボタンがクリックに反応しない、リストビューセルがクリックに反応しない
また、私は自分の仕事を別の目で見てバグを指摘したいと思いますが、私が1人のチームであると言ったように、上司が私に指示し、彼は会社を所有し、アプリのアイデアを持っていますが、 c ++や最近の言語も知りません(cobal?私はすべてだと思います)。会社の知的コード/プロパティに違反/見せびらかすことなく2つ目の目を取得する方法に関するアドバイスはありますか?
...そして、この有給のインターンシップを辞めないという選択肢はありません。契約では、12ヶ月の契約の6ヶ月前に辞めた場合、年収の30%を支払う義務があると言われています
問題を100%再現できる場合は、最後のステップにブレークポイントを設定します(できるだけ早く)。コールスタック全体を確認すると、予期しない値がどこかにあるか、または呼び出すべきであるがそうではないものに気付くはずです。
編集:
そして、もしあなたが機知の端に座ってバグを修正しようとしていて、ここに投稿しているなら、いくつかの輝かしい光のアドバイスが得られることを期待して、離れて。頭をすっきりさせて、後で戻ってきます(できれば明日か週末の後)。特定の問題の解決策を探すために丸一日丸一日かけて過ごし、翌日戻ってきて頭をはっきりさせて、10分以内にそれを見つけた。
デバッグとは、問題を特定して正確に理解することです(修正の適用と比較して)。
デバッグの際に注意すべきことの1つは、さまざまな理論の後にジャンプしていることに気づき始めた場合です。これは、実際には時間がかかることが多く、考えられる問題を体系的に排除しないためです。
通常、これらのタイプの状況をデバッグする最良の方法は、システムを小さな部分に分解し、各部分を分離して動作させ、複雑になる各要素を1つずつ追加していくことによって、それが壊れるまで退屈な体系的なアプローチです。次に、正確な問題を特定しました。この方法は少し退屈で前もって作業が必要と思われるかもしれませんが、複雑なソフトウェアのデバッグを試みている間、変数を削除し、頭の良さを保ちます。
これらは私が過去にやったことのほんの一部ですが、明らかにそれらがすべての状況ですべて機能するわけではありません:
私は通常、バグを解決するときにこのアプローチをとります。
この時点では、問題に焦点を合わせている過程で多くのことを学び、何をすべきかがわかっているので、通常は何が起こったのかは明らかです。または、私がフォーラムで尋ねることができる非常に焦点を当てた質問があります。
次に、問題の修正を試み、ステップ1で作成したステップバイステップを使用して、バグが修正されたかどうかを確認します。
以前のすべてのアドバイスは優れており、その多くはバグ/エラーに関する仮定を確認し、デバッグプロセスに従ってエラーを特定することを目的としています(場合によってはバグの周囲の環境を調べ、場合によってはコード内で直接調べる)。
このアプローチは、年功や専門知識に関係なく、常に機能するとは限りません。場合によっては、問題に対する別の目が必要になることもあります。あなたと問題やデバッグセッションを確認する人を見つけましょう-多くの場合、コードを話すだけでエラーにつながります。
ジュニアプログラマとして手元の作業を行うように割り当てられている場合、自分ですべてを処理できると信じている人が少なくとも1人います。
次に、上司に助けを求める前に、スクラップペーパー、バグの追跡に使用した手順/方法のリスト、バグの追跡状況、各方法を断念した理由、および何を学んだかを書き留めます。それぞれの試みで。また、これまでにプロジェクトについて学んだことを要約します。
おそらく、これを書き終えたら、何ができるかは盲目的に明らかになるはずです。もしそうなら、あなたはバグを再現するためにそれ自体が明らかになったものに従って、修正を試みてください。そうでない場合は、上司と話すことができる基礎があります。あなたが何をしたかを示さずに彼らの助けを求めるならば、彼らはあなたに否定的な印象を与えるかもしれません。
しかし、頭を片付け、週末の後に戻ってきた場合、誰かの助けがなければ、すぐにそれを解決できるかもしれません。それはいつでも起こります。
他の人が言ったように、1)それを確実に再現できること、および2)デバッガーでそれが発生するポイントまで前進すること。
それができない場合は、何らかの理由で、バグが発生しない別のバージョンのコードが必要な他の2つの方法があります。
両方のバージョンのコードをデバッガーで並べて実行します。悪いものが良いものとは異なる何かをするまでそれらを一緒に歩きます。
良いバージョンと悪いバージョンのコードを交互に実行します。 diffまたはバージョン間の違いのその他のリストを用意します。次に、どちらかのバージョンのコードを少しずつ変更して、他のバージョンとより密接に一致させるようにします。悪い方が良くなった場合、または良い方が悪くなった場合は、変更を取り消して小さな変更を行います。このようにして、私はバグに帰着します。それは「問題の両側に乗り込み、中心に向かって取り組む」ことだと思います。このメソッドはデバッガーを必要としません。
問題の再現が難しい場合は、スタックダンプなどdoesが発生したときに、できるだけ多くの情報を入手する必要があります。だから私はそれらの診断を取得し、問題が発生するのを待つことができることを確認し、それを見つけるのに十分な情報を得ることを望んでいます.
方法がまったく異なるので、再現がどれほど難しいかを知る必要があります。欠陥を確実に再現するには、欠陥の原因を自動化します。デバッガーとデバッグトレースを使用します(トレースは、競合状態の種類の欠陥への影響が最小です)。系統立ててください。一度に1つのステップで、各ステップは、すでに知っていることを確認する場合でも、より多くの情報を提供します。意外な結果が出た場合は、先に進む前に100%理解してください。非常に遅いですが、十分な時間を与えると、常に最終結果に到達します。
それを再現できない場合は、問題があります。修正したことをどのように確認しますか。デバッグコードを入れて、そのままにしておきます。最終的に、「Closed:DNR」は有効なオプションですか。 (再生しませんでした)。ビジネスでは、最終的にはコスト/利益の決定です。
ライブラリが正しいと思い込まず、正しいことを確認してください。
休憩して、費用対修正の必要性について実用的になり、何よりも、誰かにあなたのそばに座って助けを求めてください。
物事のスキームでは、再現可能なバグは(比較的)簡単です!どうして?バグがなくなるまでいつでもコードを最小限に抑えてから、戻って作業して、どのコードが原因となっているかを突き止めることができるからです。これが1つの方法です。それは再現可能です、あなたはあなたのコントロールの下でそこに生き物を持っています。あなたはそれをつついて、それを実験することができます。必要に応じて、解剖することもできます。
最初の目的は理由を理解するバグがyourコードで発生していることです。最初は修正しようとしないでください。 理解するそれを試してみてください。理解せずに修正しようとすると、ハッキングされ、解決しても技術的負債が発生する可能性があります。
アプリの動作を1行ずつ確認します。変数値を監視します。制御の流れに注意してください。あなたの理解があなたがそれがそうあるべきであるとあなたに告げるものから、最初に行動はどこから逸脱しますか?オペレーティングシステムがアプリにイベントを送信する方法を理解していますか? 「ブラックボックス」の問題に悩まされている場合、コンパイルされたライブラリ/フレームワークのソースを取得できます。必要に応じて、より深いレベルでステップスルーできますか?
このバグを引き起こさないバージョン管理システムのコミットがありますか? (バージョン管理を使用していますか?)そのようなコミットがある場合は、履歴をバイナリ検索して、バグが発生した場所を正確に見つけることができます。
あなたの目的は、(1)理解-原因を特定し、その目的を達成すること、(2)アプリの動作を詳細に調査、理解すること(3)問題を解消して問題を特定し、そのデルタを調査して理解することですそれを可能にした
しかし、本当に行き詰まっている場合は、何週間もそこに座ってはいけません。あなたもあなたの組織の誰かに伝える必要があります。特定のポイントを通過できる場所を支援するように要請することは、経営者に進行の障壁にぶつかったと感じていることを伝えることは確かにあなたの義務です。ただし、学習と理解に焦点を当てたさまざまな角度から攻撃すると、この問題を解決できる可能性があります。
ここにたくさんの良い答えがあります。他のいくつかのヒント:
UIが単独で存在することはほとんどありません。バグの再現に必要な最小限の機能セットでテストプログラムを作成します。 UIが適切に設計されている場合は、失敗しているUIコンポーネントを分離し、テストプログラムでそれらを分離して実行できるはずです。問題を再現できますか?その場合は、UI構造またはフレームワークに問題がある可能性があります。 UI構造を確認します。特に、非表示の要素に注意してください。そのListViewをクリックしたときに何が起こるかを正確に調べて、それが応答しないようにします。どのイベントハンドラーが呼び出されますか? UIフレームワーク自体にバグが存在する可能性があることを覚えておいてください。その結論にジャンプしないでください。ただし、完全に除外しないでください。簡単なテストは、Mosyncのバージョンをアップグレードし、症状が発生するかどうかを確認することです。
失敗:テストプログラムには何が残っていますか?残っているもののすべてのコンポーネント、特に実行中のスレッドをすべて理解します。バックグラウンドでデータベースのメンテナンスをしている何か?ある種のファイルスプーラー? NSAユーザー動作監視コード?UIはこれらのコンポーネントの一部(おそらく裏で)で動作していますか?UIはどのバックグラウンド操作に依存していますか?
バグの難しさを考えると、かなりの時間をかけてコードを読んでいる間、バグを不明瞭にする可能性があるいくつかの悪い習慣に注意してください。具体的には、これはありますか?
try {
SaveTheWorld();
} catch (std::exception& ex) { /* oh it didn't work, let's just ignore it */ }
それは信じられないほど貧弱な習慣であり、そのためかなり一般的です(クラッシュしなかったようです!)。少なくともそれをログに記録するために、それを実行しているコードを必ずアップグレードしてください。できれば、誤った例外処理を完全に削除してください。 (経験則として、例外が何であるかわからない場合は、それを処理する準備ができていません。)CスタイルのAPIと相互作用している場合は、エラーコードの戻り値がドロップされていないか確認し、対話しているツールからエラーステータス情報をチェックしています。
テストプログラムが障害を適切に処理する方法を確認し、このようにして作成したログを読みましたが、まだバグを強調するものは何もないので、プローブできるインターフェイスを探します。内部で発生するはずのネットワークトランザクションはありますか?その場合は、Wiresharkを使用してください。データベーストランザクション?クエリロギングを試すか、データベースサーバーのステータスを確認してください。ファイルシステムまたはネットワーク共有がヒットしていますか?中間ファイルを確認するか、デバッガを使用してI/Oをトレースします。ハードウェアI/O?監視と調査。経験的になる。 UIは、予期しないバックグラウンド操作でハングアップする可能性があります。
最後に:慌てる必要はありません。クールに保ち、何を試したかを追跡します。それでも見つからない場合は、雨の日に追跡される「既知の問題」になる必要があります。それがそのように行く必要がある場合、あなたはその決定を正当化するためにたくさんの資料が欲しいでしょう。