コードのデバッグ方法(悪夢のような状況)


16

私は仕事でアプリケーションのデバッグを頻繁に行います。これは、テスト環境と実稼働環境を含む、ビジネスに展開するBIアプリケーションです。これらの制約に基づいて、人々が提案できるアプリ/ツール/メソッドがあるかどうか疑問に思っています:

  1. ソフトウェアはテスト環境がないカスタムサードパーティアプリケーションに依存しているため、クライアントサイトまたはローカルでデバッガーを使用することはできません。(編集:公平にするために、場合によってはローカルでデバッグすることができます。コアコード以外を使用しない場合、問題のあるコードの多くは、サードパーティ固有の通信をカプセル化するdllにあります:ソケット、プロセスパイプ、soap呼び出し、コアコードの動作を変更するカスタムロジック。通常、クライアントの実装または拡張中に、この領域に新しいコードを記述します。

  2. アプリでは実質的にロギングは行われません。単体テストはありません。

  3. バージョン管理には、フルソリューションの1つのバージョンしかありません(ソースセーフ2005を使用)。そのため、ソリューション全体の以前のバージョンを取得することはできず、個々のファイルのみを取得することができます。(誰かがこれを回避する方法を知っていない限り)。

  4. ローカルでは再現できません。テスト環境では再現できないことがよくあります(テストと本番が同じバージョンではない可能性が高い)。

  5. クライアントが使用しているバージョンがソースセーフのバージョンと異なる可能性が高くなります。これは、個々のファイルが更新され、その特定のクライアント用のカスタムロジックが埋め込まれているためです。多くの場合、バイナリが更新され、他のいくつかのバイナリを変更する必要がありますが、コミットが完了すると、これについての記録や知識はありません。よくあるエラーは、クライアント環境で「関数/メソッドが見つかりません」または「メソッド呼び出しに指定されたパラメーターが多すぎる/少なすぎる」ことです。

  6. これは.net VBソリューションです

  7. クライアントサイトにはソフトウェアをインストールできませんが、ローカルにインストールできます

  8. 私たちのアプリケーションは非常にカスタマイズ可能ですが、残念ながら、カスタマイズロジックは、クライアントごとにデータベースに加えられたカスタム変更を含め、フロントエンドからデータレイヤーに至るすべてのクラスとファイルに分散されています。

  9. コードには実質的にコメントはありません。アーキテクチャに関するドキュメントはありません。APIに関するドキュメントはありません。私たちが持っている唯一のものは、何が起こっているかをいくらか説明する何百もの電子メールチェーンです。コードを知っているのは元々コードを書いた人だけですが、彼らはもはや開発者ではないので、それほど関与しません。

そして、あなたがそれを言う前に...はい、私は知っています。自分も撃ちたいです。スパゲッティコード、何百ものコンパイラ警告、そして本当に修正すべきポリモーフィズムが存在することは助けにはなりませんが、私はそれに言及していません。

私が遭遇する最も一般的な種類のエラーは、null参照エラー、無効なキャスト、および欠落した関数/関数シグネチャの不一致です。幸運なことに、イベントビューアーはクラス、メソッド、例外メッセージをログに記録します。それは最も有用ではありませんが、それでも何かです。最悪なのは、スクリーンショット以外にトレースや再現手順がないエラーであり、上記のような一般的なエラーメッセージです。環境が適切に構成されておらず、それが後でなくなることを祈るだけで、それらが発生した理由を見つけることができない場合があります。

私はこれが少し暴言として出てくることを知っています、そしてある程度はそうです。しかし、私はオプションに必死です。私が使用できる他の方法/ツールはありますか?


43
履歴書はありますか?
ロバートハーベイ

5
「私も自分を撃ちたい」の+1。Source Safe 2005、痛い。まあ、少なくとも素晴らしい歴史のレッスンに「集中」する必要があります-あなたは基本的に時間旅行者です!「だからこそ、私たちはもうそれをしないのです」という10年にわたる慎重に開発された知識の教訓を学びます。ゴッドスピード、バッタ。
ブライアン

7
要件#1を考えると、この混乱をデバッグするのに効果的な唯一の方法は、千里眼であることです。真剣に、これをクラップスシュート以外のものにする魔法の弾丸はありません。デバッグは運の問題であるため、いくつかの点でこれはあなたからの圧力をいくらか取り除くはずです。それとも、あなたの経営者はあなたに幸運になるように命令するつもりですか?これは明らかに持続可能ではないため、他の機会を探す必要があります。
チャールズE.グラント

14
ここに実際のキャリアアドバイスがあります:ひどいソフトウェアエンジニアリングの慣行がある家に長くかかりすぎると、必然的に起こる問題の悪い開発者であると経営者に非難されるでしょう。私はそこに行ったことがありますし、他の人たちも同様だと思います。最良の場合でも、悪い開発習慣につながります。
ロボットをゲット

2
これらの状況をどのように管理するか:市場をはるかに上回って報酬を受け取っていない場合、他にやることがあります。
ケビンクライン

回答:


22

ロバートハーヴェイのアドバイスはおそらく最良ですが、キャリアアドバイスはトピックから外れているため、どのような答えが得られるかを示します。

あなたはイバラと泥とイライラ山ヤギに覆われた非常に急な山の底にいます。簡単な方法はありません。あなたがトップに到達したい場合、あなたは一度に途方もない痛みを伴うステップを1つ上に押し上げなければなりません。

物事どのように機能するかを正確に知っているようです。他の誰もあなたを助けてくれないなら(再び、キャリアアドバイスを無視して)、あなたの唯一の選択肢はあなた自身でこれらのものを修正し始めることです。

まず、すべてが神聖であるために、そのようなものを実際のバージョン管理システムで入手します。Source Safe以外はほとんど何もありません。SourceSafeは、悪臭を放つゴミの山として知られています。 git無料で、かなり簡単にセットアップできます。過去のバージョン管理の欠如の問題を修正することはできませんが、少なくとも問題が将来にわたって続くのを止めることができます。

次に、ロギングを調べます。ロギングシステムを見つけて、最悪の場合、ログシステムを作成し、使用を開始します。クライアントサイトでも使用できるものを使用してください。そうすれば、物事が横向きになったときに、少なくとも何かが手に入ります。

そして、少なくとも新しい変更を加えるために、テストの作成を開始します。

砂糖のコーティングはありません。ここでは、多くの作業を伴わない、またはこれをキャリアの問題として扱う答えはありません。


私を信じて、私はアサート、ガード、ロギングを追加するだけで、おそらくデータ層も書き直したいでしょう(典型的な設定の問題を診断するために設定バリデータを書いています)。残念ながら、それは私次第ではありません。ソースに安全なものをプッシュするように要求することができますが、典型的な応答は「あなたの意図は良いですが、これは私たちが焦点を合わせるべきものではありません」です。悲しいかな、私は1/2年の経験を持つジュニアです。しばらくこの山に登ります。
-Igneous01

9
@ Igneous01正直なところ、登る別の山を見つけてみてください。他の場所での労働条件は完璧ではないかもしれませんが、少なくともほとんどはあなたが経験しているものよりもかなり良いと思います。ゲートキーパーが「これは私たちが注目すべきことではない」とあなたの改善を拒否した場合、それは彼らの決定であり、彼らはその失敗したポリシーの結果を刈り取ります。問題は、彼らがそうするまで彼らに固執したいですか?
cmaster-モニカの復元16年

6
そして、悪いポリシーが失敗すると、反対する人も含め、関係者全員が悪いように見えることに留意してください。
ロボット

1
はい、ロギングとトレースを開始します。また、文書化を開始し、コメントを追加します。少しずつ、すべてが加算されます。また、チームではないにしても、会社に元のコーダーがいれば幸運だと言います。経営陣にプッシュして彼らにアクセスを提供する可能であれば、質問で絶えずアプローチするよりも、いくつかのドキュメントを作成するように説得します。
Mawgはモニカ回復言う

4
@ Igneous01:走って、歩かないで。この場所は病気であり、あなたを病気にします。
モニカの復活-M.シュレーダー

8

1)クライアントサイトでデバッガーを使用できない...

それは完全に正常です。

...またはローカル

これが問題です。

2)アプリでは実質的にロギングは行われません。

ロギングプロダクションデバッグです。

単体テストはありません。

まあ。ただし、すべて共通です。

3)バージョン管理には、フルソリューションの1つのバージョンしかありません

次に、バージョン管理を使用していません。

4)ローカルで再現できず、多くの場合、テスト環境で再現できません(テストと本番が同じバージョンではない可能性が高い)。

したがって、デプロイされたクライアント環境のみがエラーを表示します。

その場合は、アプリケーション・コードに埋め込まdisgnosticロギングを必要とする()トラップと[完全]レコードの[致命的]エラーと(b)があり、追加、継続的、診断生成するために、オンデマンドで「ダイアルアップ」することができ便利でを問題を追跡します。

5)クライアントが使用しているバージョンが、ソースセーフのものと異なる可能性が高いです。

繰り返しになりますが、バージョン管理を使用していないだけです。

8)私たちのアプリケーションは非常にカスタマイズ可能です

それはかなり典型的です。

サイト固有の違いは、バージョン管理「ブランチ」を通じて管理する必要があります。

9)コードには実質的にコメントはありません。

繰り返しますが、開発者は「自己文書化」コードを書くので、それはあまりにも一般的ですよね?
または、少なくとも、作成した日に理解しているコード。

アーキテクチャに関するドキュメントはありません。

まあ。

APIに関するドキュメントはありません。

ああ、親愛なる。

そして、あなたがそれを言う前に...はい、私は知っています。自分も撃ちたいです。

番号; このようなものをすべて書いて、文書化されていない、維持できない混乱を作成し、新しい牧草地に移り、良心的な混乱を残した人々を撃ちたいと思うでしょう。

私が遭遇する最も一般的な種類のエラーは、null参照エラー、無効なキャスト、および欠落した関数/関数シグネチャの不一致です。

ヌル参照と無効なキャストは実行時エラーです。ある程度まで、あなたはそれらを期待するべきであり、彼らが頻繁に得ているという事実は、元の作者による防御的なプログラミングの欠如(または楽観主義の過剰)を示唆しています。

関数シグネチャの不一致により、ビルドが破損ます。それらは「壊れたビルド」を引き起こし、決して外に出てはなりません!


2
「あなたのコードを維持することになった人が、あなたがどこに住んでいるかを知っている暴力的なサイコパスであるかのように常にコードします」
-PerryC

実行時エラーは、防御的なプログラミングの欠如よりも理解の欠如によって引き起こされます。防御的プログラミングは、コードが機能しないという事実を隠す方法にすぎません。
user253751

1
「アーキテクチャについてのドキュメント」は、通常「何のアーキテクチャ」...意味しない
gnasher729

The site-specific differences should be managed through Version Control "Branching".-これが最善の方法だとは思わない。構成ファイルと機能の切り替えの使用は、より一般的であり、推論するのが簡単なようです。
sixtyfootersdude

5

ロギングから始めます。これが最大の影響を及ぼします。Log4Netなどのログベースをコードベースに実装します。コードの動作のログを開始します。

デバッグはローカルで可能です。そうでない場合は、シンボルファイル(PDB)を取得して、サードパーティのdllをデバッグして、発生している問題の全体像を把握できるようにします。WINDBGなどのツールは、システムがクラッシュした場合にどのDLLに問題があるかを示すことができます。クラッシュが発生したときにメモリダンプを取得するように任意のサーバーを構成できます。これは基本的に、問題が発生したときに何が起こっていたかのスナップショットです。ダンプをローカルで調べて、何が起こっているのかを知ることができます。デバッグが不可能な場合、それを可能にするために作業してください。デバッグに必要な手順を文書化します。複雑なシステムでは、完全にデバッグするために非常に多くのセットアップが必要になる場合があります。

バグ追跡...使用していない場合は、使用を開始してください。これは、適切なバージョン管理システムと密接に関係しています。基本的に、コードの欠陥と改訂の追跡を開始します。システムの履歴の構築を開始します。

静的コード分析を実行します。ReSharperのようなツールに投資してください。考えられるすべてのnull参照例外およびその他の不適切なコーディング手法をすばやく指摘します。数回クリックするだけでコードの形状を改善し、コードの書式設定、変数の命名などの退屈な項目を自動化できます。コードを測定し、コードメトリックを使用してリファクタリングのホットスポットを見つけます。

リファクタリングと単体テスト。おそらく、書かれたコードのほとんどはあまりテスト可能ではないので、テストを追加しようとは思わないでしょう。新しいコードは、テストプロジェクトを作成し、ユニットと統合の両方のテストの作成を開始します。単体テストが失敗した場合は、ビルドに失敗します。そのため、リファクタリングするときにテストが必要です。テストに関する1つのことは、アプリケーションまたはコードベース全体をロードせずに、メソッドを呼び出してそのメソッドをデバッグするテストを作成できることです。これは、問題のトラブルシューティングに役立ちます。

必要に応じて部族の知識を文書化します。コードは自己文書化されている必要があるため、コメントはまばらになりますが、多くのシステムには「異常な」方法があり、コーディングWIKIまたはその他のタイプの非公式リポジトリで指摘されています。また、コーディングの標準と実践を考え出すことを検討してください。Resharperなどのツールセットを使用して、これらの標準を実施します。ほとんどのコードはおそらく標準やガイドラインに従っていないため、作成された新しいコードに標準を実装します。

あなたの新しい以来、私は義務のツアーのようにこれを扱います。6か月から2年。その後、滞在するか先に進むかを選択します。物事を前日より少し良くすることで満足を得る。


4

まず、上記のすべて...同じ。

いくつかのヒューリスティック:

  • 開発コンピューターでソース管理を使用します。それは私がやった最高のことです。私たちが持っているプロジェクトのバージョン管理の代替ではありません。これは、大胆に試行錯誤し、ハックし、同時に問題を同時に独立して作業するなど、驚くほどの自由度を提供するツールです。
  • コメントを追加する範囲で、パブリックインターフェイス要素に優先順位を付けて、インテリセンスを活用します。デバッグアドベンチャー中に解読するときにこれを行います。
  • マイナーなリファクタリングで粘り強くしてください。遅かれ早かれ、与えられた大量のコードに対して、クラス全体で冗長コードを乾燥させるような大きなリファクタリングを可能にするクリティカルマスに到達するでしょう。
  • 同じバージョン管理コミットでコードの再フォーマットと実際の変更を混在させないでください。
  • 堅実な原則
    • 単一の責任を無視しないでください。これはオブジェクト指向の約束へのです。私見では。
    • Open / Closedを常に無視します。
    • ここでは新しいコードについて話していません。
    • 意図的な設計なしでインターフェイスを作成すると、メンテナンスが妨げられます。
  • リファクタリング
  • 一部のコードファイルでは、デバッグを試みる前に、完全な再フォーマット、変数名の変更などが必要です。単体テストなしでVisual Studioのリファクタリングメニューを使用することをためらわないでください。
  • 置き忘れられない唯一のドキュメントは、コードファイルにあります。
  • バージョン管理を取得するときは、VCプランを先取りしてください。そしてそれを文書化する!そして、ブランチの命名規則、主要なソフトウェアバージョンとマイルストーンを強調するタグを考え出します。
  • 良い機器を使用する
  • ラバーダッキーデバッグの練習
  • 起こりうる最悪の事態は、彼らがあなたを解雇しないことです。

編集

.NETでのブラウンフィールドアプリケーション開発

この本を試してください。最初のカバースルーリードスルーは、おそらく最高です。この本は、攻撃の全体像、可能性、および戦略的および戦術的な計画の両方について考えるのに役立ちます。

突き出す

可能であれば、1.5年とどまります。あなたが経験的な進歩をしているかどうかを知るのに十分な長さ。2年の経験があるか、6か月の経験があるかを4回知っています。

「1/2年の経験を持つジュニア」なので、潜在的な雇用者は、ハッキングできなかったため、早期に救済されると考えています。あなたがz、y、xを学んだと言って一つのことは、いくつかの名前を取り、いくつかのお尻を蹴った-しかし、あなたの能力に貢献することは許可されませんでした。もう1つは、説明のためにジョブ、コード、管理などを単純に危険にさらすリスクです。

私はこれに基づいていないかもしれませんが、私の「最高の時間と最悪の時間」は私の最初の仕事であり、たまたま文字通りメンテナンス不可能なコードでした。優れたスーパーバイザーがいました(残りはすべて管理の近親交配プログラムからでした)。いくつかの重要なプログラムを書き直すスペースをくれました。その経験は啓示でした。

編集を終了


同じバージョン管理のコミットでコードの再フォーマットと実際の変更を混在させないでください。-すばらしいアドバイス
-kiwiron

0

(5)を最初に修正する必要があると思います。本番環境で実行されているコードがわからない場合、問題を再現して修正する安全な方法はありません。これにより、予見できない問題や再現できない問題が発生する可能性があるため、導入するその他の変更が危険になります。

どのバージョンのコードとどのライブラリがデプロイされているかを把握するために、いくつかの探知作業とおそらくリバースエンジニアリングが必要になる場合があります。(そして、展開されたすべてのコードをソース管理と一致させるために、一貫したビルドおよび展開システムが必要です。)

さまざまな展開を複製するには、複数のテスト環境を構築する必要があります。(もちろん、最も簡単な修正は、新しいクリーンビルドを作成し、どこにでも一貫して展開することですが、これは不可能だと思われますか?)

展開された正確なバージョンがわかっていて、対応するテスト環境がある場合にのみ、コードの修正/改善を試みてください。

次の優先事項は、どこにでも展開できる単一のコードベースに統合することです。カスタマイズのためにコードのさまざまなバージョンが展開されているように聞こえますか?単一のバージョンに統合してから、カスタムロジックの構成スイッチを使用する必要があります。

この後、デバッグを容易にするために、コードベースを慎重に改善し始めることができます。ロギングの追加は、おそらく最もリスクの低い改善です。

自動テストを追加することもできますが、テスト用に最初に設計されていないプロジェクトにユニットテストを追加するのは難しい場合があります。代わりに、自動化されたエンドツーエンドの統合テストから始めることをお勧めします。これらは設定するのが難しいですが、ソリューションを再設計する必要はないため、リスクは少なくなります。


0

チーム内の問題を無視すると、最初に対処する必要があるのは、実稼働中のものと一致するコードをデバッグすることです。そうしないと、「ソース管理」にあるコードで既に修正されたバグを追跡している可能性があります。これは.NETなので、本番バイナリを簡単に「逆コンパイル」して、コードと現在のコードを比較できます。これは簡単な作業ではありませんが、成功した場合、これはリリースされたバージョンにタグを付けることができる、より良いソース管理ツールの強力な議論です。


逆コンパイルするということは、IDA Proのようなものを使用してマシンコードを表示するということですか?ここでだれもアセンブリを知らないので、それを使用するのはおそらく私だけでしょう(そして、私は非常に基本を知っています)。
Igneous01

まあ、これは.NETなので、バイナリはマシンコードではなく、CIL(en.wikipedia.org/wiki/Common_Intermediate_Language)にあります。特に難読化されていない場合、これはかなり簡単かつ正確にc#またはVBコードに変換できます。たとえば、ILSpy(ilspy.net)で試してみることができますが、おそらく他にも使用できるツールがあります。
20cは
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.