17

:私のターゲットの懸念は、通常のMSILでCLRをターゲットにするC#です。これは、それで機能するが、より一般的なケースでは機能しない場合です。

既存のソース デバッグ サポートの例

最近、ユーザーが pdb ファイル内のソース パスを別の場所を指すように書き換えることができるSourcepack プロジェクトがリリースされました。これは、アセンブリのソースがあり、それをビルドしたときとまったく同じファイルシステムの場所に取得したくない場合に非常に便利です。

http://lowleveldesign.wordpress.com/2011/08/26/sourcepack-released/

オープンソース プロジェクトの場合、プロジェクトのユーザーがシンボルとソースを簡単に取得できるようにする方法として、http://www.symbolsource.org/を使用することは優れたアイデアです。

問題

ただし、法律上または便宜上の理由から、このようなアプローチを使用することがあまり現実的でないプロジェクトが非常に多くあります。また、プロジェクトをデバッグしている可能性のある人々のセットは、比較的小さいか、含まれている可能性があります。

デフォルトでは、プロジェクトの pdb にはディスク (IIRC) 上のファイルへのポインターが含まれており、ソース インデックス作成により、ソース サーバーを使用して、ソースの場所 (たとえば、バージョン管理システム) へのポインターを埋め込む機能を追加できます。実際にソースをフェッチするためのポインター。

ゴール

実際のソースを pdb に入れるだけ (事実上、現在 PDB に書き込まれているポインターを逆参照するだけ) の方が簡単なようです (デバッグや内部専用などの特定のビルドの場合)。その場合、ソース サーバーの部分全体を (少なくとも理論的には) スキップして、デバッグ時のストーリーへの依存関係をいくつか排除できるようです。ソースを圧縮して保存するかどうかは、ほとんど直交していますが、既存のデバッガーの実装を簡単にするために、最初のパスではおそらくそうしません。

PDB マッチング バイナリ ストーリーはすでに非常に優れているため、ソースを PDB に配置することは、ソース サーバー ポインターよりも優れています。ポインターは時間の経過と共に破損する可能性があるためです (ソース管理システムの移動、別のシステムへの変更、またはしかし、PDB にある実際のソースは「永久に」有効です。

これは「ソース サーバー」サポートとどう違うのですか?

(これは、利点が何であるかを尋ねるTigranのコメントの後に編集によって追加されました)

これを比較する必要がある「ベースライン」シナリオは、現在「通常の」ソース サーバー インスタンスを使用した「通常の」デバッグ エクスペリエンスのシナリオです。そのシナリオでは、(AFAIK) デバッグ エンジンは PDB から (代替ストリームを介して) ポインターを取得し、登録されたソース サーバーを使用して、そのポインターを介してソースを取得しようとします。通常、特定のアセンブリには複数のソース ファイルが含まれるため、ベースの場所を含む単一のポインターが存在するか、PDB (またはその他のもの) に複数のポインターが存在するかのいずれかですが、それはこの議論とは直交するはずです。

ソースを非表示/アクセスできないようにしておくことが望ましいプロジェクト (Windows、Office、Visual Studio などを含むほとんどの Microsoft 製品) では、PDB にポインターを含めることは、実際のソースを含めるよりもはるかに優れています (たとえそれがあったとしても)。暗号化されています)。このようなポインタは、必要なネットワーク アクセスとアクセス許可がなければ意味がありません。したがって、このようなアプローチは、ソースにアクセスできるかどうかを心配することなく、地球上の誰にでも PDB を出荷できることを意味します (最悪の場合、ソースがどのようにアクセスされるかを垣間見ることができます)。木が配置されていると思います)。

ただし、この「ソースを非表示にする」利点が存在しない 2 つの大規模なプロジェクト (具体的にはビルド) があります。

1 つ目は、とにかくソースにアクセスできる人だけが使用するビルドです。自分のマシンで実行され、そのマシンから離れることのないビルドは良い例です。攻撃者はソースを取得するためにファイルシステムからファイルを読み取る必要があるため、1 つのファイル (.cs) と別のファイル (.cs) から読み取る必要があります。 pdb) は、攻撃の難易度/ベクトルの点で比較的小さな違いです。同様に、マシン上の pdb にアクセスする人々がソースに「通常」アクセスできる人々と等しいか、そのサブセットであるテスト/ステージング環境に実行されてプッシュされるビルド。

2 つ目は (やや明らかに) オープンソース プロジェクトであり、プロジェクトのソースはすでに誰にでも公開されているため、ソースを隠しても何のメリットもありません。

これは、代わりに暗号化された形式でソースを含めるように比較的簡単に拡張できることに注意してください (フォーマット/エンコーディングデータも保存する必要があることについては既に話しているため)。 「通常の」ソースサーバーを使用するだけではありません。

利点?

上記の説明が邪魔にならないので、これを許可することの潜在的な利点のリストには、現時点で私の頭に浮かぶものが含まれます (ただし、これらに限定されません:):

  • ソース サーバー サポートの設定に対処する必要はありません。It Just Works (IJW)、少なくともデバッガーが pdb を調べることを知っていた場合。
    • それまでの間、ソースを抽出して呼び出し元にフィードバックする単なるダミーである「固定」ソース サーバーを実行することもできます。このような構成は、(たとえば、localhost を使用して) 誰にとっても同じである可能性があり、ソース サーバーを実際に構成する現在の必要性を排除します。
  • ビルドに「ソースのインデックス作成」を含める必要はありません
    • とにかくビルドはソース ファイルを読み取り、pdb ファイルを書き込むため、pdb に書き込まれた内容を変更するだけであり、ネットワーク呼び出しを実行したり、まだメモリにないデータを読み取ったりするためのビルド時のパフォーマンス ヒットはありません。
    • ソースを入れるための「ネイティブ」ビルドのサポートまでは、単純なビルド後のステップである可能性があります.PDBファイルの読み取り/変更の作業をすでに行っているため、Sourcepackプロジェクトの小さなフォークを介して最初に実装される可能性があります:)
  • ソース管理システムを持つチーム/プロジェクトに依存しない
  • ソース管理システムにチェックインされる各ファイルの特定のバージョンに依存しない (ほとんどの人は、IDE で実行するすべてのビルドをチェックインするわけではありません)
  • ファイルがある特定のソース管理システムにアクセスする必要はありません
    • たとえば、DVCS の場合、PDB ポインターは git や mercurial などの「ランダムな」インスタンスを指している可能性があり、必ずしもアクセスできるインスタンスである必要はありません。
    • そのバージョンを追跡して、アクセスできるソース管理サーバー インスタンス (そこに存在する場合でも) までさかのぼるソース サーバー ツールは、AFAIK ではまだ存在しません)。
  • プロジェクトが死んだ(削除された)または移動しても問題ありません
    • たとえば、プロジェクトがセルフホステッド、sourceforge、github、bitbucket、codeplex、code.google.com などの別のプロジェクトに移動した場合などです。
  • デバッグしているマシンにネットワーク アクセスがない (または不十分な) 場合は問題ありません
    • たとえば、問題をデバッグするために「ネットワーク KVM」をボックスに実行しているが、ネットワークがないか、切断されたネットワークとしか通信できないため、ソース コントロール サーバーにアクセスできない場合)。
  • 極端な場合、ビルドからプロジェクト ソースの一部を復元する機能。;)

注: 別のアプローチとして、実際のアセンブリにソースを含めることもできますが (たとえば、リソースとして)、pdb の方が適しています (pdb なしでビルドを出荷するのは簡単で、ソースが pdb にある場合は通常の実行時のパフォーマンス ヒットはありません)。アセンブリは同じコードで同じサイズなどであるため)

実装方法は?

表面的には、この種のサポートを追加するのはそれほど難しくないように見えますが、実際には単純なことではなく、関連するメカニズムについて十分に知らないためだと感じています.実装する。:)

私の推測では、次のようなものになります。

  1. Sourcepack と同様の処理を行うビルド後のステップを追加しますが、ポインターを変更する代わりに、実際のソースに置き換えます。
    • ソースサーバーが何をする必要があるかによって、プレフィックスを付ける必要があるか、実際のソースが別の代替データストリームにあり、「ポインター」が「source-in-pdb:ads-foo.cs」に更新されます。 」または何でも。接頭辞またはポインタには、ソースファイルの保存方法も含めることができます(ファイルのエンコードとともに、非圧縮、gzip、bzip2など)
  2. 問題の pdb からソースを実際に抽出して返す「ソース サーバー」を実装します。
    • ソースサーバーの「API」がPDBの場所を取得するのに十分な情報を持っているかどうか、ましてやコンテンツを実際に読み取る権限があるかどうかはわかりません。

サニティーチェック?

上記のせせらぎが邪魔にならないので、質問は実際には次のとおりです。

  • このようなものはすでに存在しますか?(もしそうなら、ポインタを提供してください!)
  • まだ存在しないと仮定すると、上記は最初のパスの実装として意味がありますか? 上記がスキップする落とし穴や複雑さはありますか?
  • 上記について「いいえ」と「はい」と仮定すると、これを引き受けるという点で意味のある既存のプロジェクトはありますか (それは近いか、既存の範囲内にあります)?
4

1 に答える 1

4

私はこれを読み、明確にするために私の理解を要約したいと思いました

現在、デバッガーは PDB を使用して、実行可能ファイルの特定のセクションを作成するためにコンパイルされたファイルとチェックサムへのディスク パスを取得します。次に、デバッガーは、ローカル ディスクと使用可能なシンボル サーバーの両方を使用してファイルの読み込みを試みます。この提案では、ファイル自体を PDB に埋め込むだけで仲介者をスキップします。エウレカ、ソースを探す必要はもうありません!

この方法でソース コードをかなり掘り下げてきた者として、すべてのデバッグ ニーズに対して 1 つのパッケージを用意するというアイデアが気に入っています。ただし、この提案について考慮すべき点がいくつかあります。

1 つ目は、ソース コードを PDB に実際に埋め込むことです。これは非常に実行可能です。PDB は、基本的には軽量のファイル データベースです。それがエンコードするものには構造がありますが、知る限り、特定のスロットに好きなものを入れることができます(たとえば、ローカル変数の値/タイプ)。特定のスロットにはサイズ制限があるかもしれませんが、大きなファイルをチャンクに分割するエンコード方式を発明できると確信しています。

2 つ目の側面は、デバッガーが実際に PDB からファイルをロードするのではなく、ディスク上でファイルを検索することです。私はデバッガーのその部分に精通していませんが、私が理解していることから、ファイルを見つけるために2つの情報しか使用しません

  1. ディスク上のファイルへのパス
  2. 上記のファイルのチェックサム (同じ名前のファイルを明確にするために使用)

これがシンボル サーバーに渡される唯一の情報であると確信しています。これにより、PDB にアクセスできないため、シンボル サーバーを実装することができなくなります (もちろん、私が正しいと仮定します)。

特定のパスのファイルの読み込みを傍受できるようにするオーバーライドできる VS COM コンポーネントがあることを期待して探し回りましたが、見つかりませんでした。

私が実行可能だと思う1つのアプローチは

  1. ソースを PDB に埋め込む
  2. ソースを既知の場所に抽出し、その場所を指すように PDB を書き換えることができるツールを用意してください。

ただし、これはあなたが望むものではありません。

于 2011-09-07T20:48:53.387 に答える