web-dev-qa-db-ja.com

可能な限り、デバッグ情報を含むライブラリをコンパイルして出荷する必要がありますか?

多くのライブラリは2つのエディションで配布されているため、開発者が外部ライブラリをデバッグするにはかなりのコスト(および苦痛)があります。1つはデバッグ情報付き、もう1つはなしです。開発者は、デバッグファイルを検索してダウンロードし、デバッグ環境でその場所を指定する必要があります。これは多くの場合、苦痛でエラーが発生しやすい作業です。これらのライブラリの構築と配布に関連する多くの作業もあります。

同時に、「リリース」バージョン(つまり、デバッグ情報のないバージョン)を廃止するように世界は変化しました。例えば:

  • 最新のランタイムは、デバッグ情報を効率的に取り除き、オンザフライで最適化して、プログラムをフルスピードで実行できます。例としては、JVMおよびJavaScriptインタープリターがあります。
  • オープンソースプロジェクト、または社外に公開されていないバイナリは、難読化される理由はありません。また、現在の多くの言語ではリフレクションがサポートされているため、デバッグ情報を取り除くことによる難読化は、たとえ効果的であっても、非常に制限されています。
  • ディスクスペースが高く、ディスクパフォ​​ーマンス(SDD)が次第に向上し、ネットワーク帯域幅も向上しています。

この質問はlibrariesに限定されていることに注意してください。私は、デバッグ情報なしでapplicationsを配布することに100%同意しています。これは、モバイルの世界では非常に重要です。

.NET PDB、およびデバッグ情報のない.classファイルで多くの問題が発生した後、プロセスとツールをdefaultが完全なデバッグ情報を含むライブラリをコンパイルして配布する世界に進化させる必要があると思います。可能であれば、バイナリ(.classファイルなど)に埋め込まれます。結局、それを行わない唯一の遠い理由は、著作権を保護することです(これは多くのシナリオには当てはまりません)。

もちろん、applicationsをパックするツールは、ダウンロード用に公開する前に、埋め込まれたデバッグ情報のすべての部分を検索して破棄するのに十分なほどスマートでなければなりません。これは、エンドユーザーがアプリケーションをデバッグすることはめったにないという事実に基づいています。

4
fernacolo

それはまたあなたの弁護士のための質問かもしれません。

デバッグ情報でコンパイルされたライブラリー(または実行可能ファイル)(例:C++、Linuxの場合、g++ -g2 -O2でコンパイルされて [〜#〜] elf [〜#〜] 形式で [〜#〜] dwarf [〜#〜] デバッグ情報)コードの リバースエンジニアリング を容易にする多くの[メタ]データが含まれています。

そのことを外部のクライアントにリリースすると、産業/知的財産の一部がクライアントに公開されます(特に、すべてのデータ構造、クラス階層、ファイルの名前、クラス、関数、変数など)。 Decompilation コードの難易度はかなり低くなります(たとえそれがかなり難しいままであっても)。

また、デバッグ情報には多くのスペースが必要です。これには、ソフトウェアを展開するときにコスト(帯域幅、データ量)がかかる場合があります。

ところで、 オープンソースソフトウェア を作成すると、作業がさらに容易になり、外部の貢献者が少し改善する可能性があるという潜在的な利点があります。

デバッグ情報をリリースできる(つまり、許可されている)場合、実際には、デバッグ情報が含まれている(別のファイルではなく)バイナリ(ライブラリまたはプログラムの)をリリースする方が簡単です。多くのコンパイラーは最適化し、デバッグ情報を出力できることに注意してください(例 [〜#〜] gcc [〜#〜] 両方の-g -O2フラグでコンパイルできます;デバッグ情報はそこにありますが、最適化のために「おおよそ」です。

ここで提案されているアイデアは、デバッグ情報をソフトウェアライブラリに同梱することで、そのライブラリ用のアプリケーションの開発が容易になるというものです。これが当てはまる場合、プログラマーは、独自のコードを機能させるために、ライブラリコードがどのように機能するかについての内部知識が必要であることを意味します。これは悪臭として知られているものです。それが真実である場合、内部の知識がプログラマーを助け、ライブラリー、特に境界関数はよく考えられていないか、クリーンではありません。この場合にデバッグ情報を提供することは、不十分なエンジニアリングと不十分なドキュメントに対するヘッジです。

エンジニアリングチームがリリースするすべてのコードを「デバッグ」用にコンパイルする必要がある場合、問題が発生します。プログラマーはリリースされたコードがないと問題を解決できないので、デバッグ用にコンパイルされたリリース済みの製品レベルのコードのシェアを見てきました。デバッガーなしではデバッグできず、コードは他の方法でデバッグするように作成されていません。したがって、リリースされたコードは常にデバッグコードになります。私はエンジニアリングマネージャーとして、このサイクルに何度も遭遇しました。

内部でキャッチされない例外があるライブラリに出くわしました。別の悪臭。これは、APIの境界でのチェックパラメータとデータの整合性の欠如が原因です。 「悪いことが起こった」のような役に立たないことを言っている多くの異なるエラー状況に使用される1つの例外がある場合、あなたは不潔なコードを扱っています。境界が内部エラーを処理し、不適切な呼び出しコードからライブラリを保護できるように、コードをより高い水準に保ちます。おそらく、実稼働環境でも実行時エラーの診断を支援するために使用できるある種のロギングがあるでしょう。

デバッグ情報を提供しないもう1つの理由は、ライブラリを呼び出すコードが、情報の非表示に違反するライブラリ自体の内部動作について仮定を行う可能性があることです。他の人のコードを壊さずに将来のリリースでライブラリを変更することが難しくなるため、これはビジネス上の問題です。コードの呼び出しによって行われる前提条件が多ければ多いほど、ライブラリの新しいバージョンを提供することは困難でコストがかかります。

プログラミングの技術は長い道のりを歩んでおり、プログラマーは今日、高品質のコードを生成する際に桁違いに効率的です。特に、Visual StudioやEclipseなどのIDEの強力なデバッグ機能により、大量の高品質コードを簡単に取り出すことができます。ただし、支払うべき代償があります。これらのツールのために、プログラマーは、実稼働コードの問題を見つけるために使用できるランタイム診断の方法をほとんど組み込んでいません。多くのプログラマーは、デバッガーでバグを再現できない限り、バグを修正するスキルを習得しません。これは、プロダクションコードにバグが発生し、すべての顧客が悲鳴を上げているときに大きな問題を引き起こしますが、プログラミングスタッフはそれを再現できません。

クリーンなコードと優れた自己文書化APIに代わるものはありません。代わりに、プログラマにデバッグコードを提供させることは警戒態勢です。

2
Jack D Menendez

いいえ、できません。デバッグビルドで実行されるコードを条件付きで含める人々は、コードがデバッグビルドでのみ実行され、リリースビルドでは実行されないことを期待しています。このコードは、非常に遅い不変のチェックでしかない場合があります。または、セキュリティの脆弱性を公開する可能性のあるコードである可能性があります。いずれにしても、コードがデバッグビルドのみを目的としている理由があると想定する必要があります。

本当の解決策は、だれもデバッグ情報を必要としないほど堅牢なライブラリを作成することです。これは、より良いライブラリ設計、より良いエラー処理、より包括的な自動テストなどを意味します。

ライブラリのユーザーもそのライブラリをデバッグする必要がある場合、彼らは時間を浪費しています。ライブラリは内部的に信じられないほど複雑な場合があります。問題のデバッグには時間がかかる場合があります。また、完全に理解されていないため、決定された「解決策」は完全に正しくない場合があります。

1
Frank Hileman