Skip to content

MS_PDBSourcePath

nishi_74322014 edited this page Aug 21, 2026 · 1 revision

ビルド環境と開発環境のソースファイルパスを一致させる(PDB)。

概要

  • 一致が望ましいが、ビルド環境と開発環境のソースファイルパスが
    一致しているケースは稀。

  • ビルド環境と開発環境のソースファイルパスを一致させる方法について調査した。

  • 結論としては、[デバッグ ソース ファイル] に指定したフォルダ以下に
    ビルド環境と構成を一致させたソースファイルが存在すれば問題ない。

補足(なぜパスが問題になるのか): PDB には
ビルド時のソース ファイルの絶対パスが記録される。
ビルド サーバが C:\build\src\Foo.cs でビルドしていれば、
開発 PC の D:\work\proj\src\Foo.cs とは一致しないため、
デバッガがソースを見つけられない。

ビルド環境: C:\build\src\Foo.cs   ← PDB にこのパスが焼き込まれる
開発環境  : D:\work\proj\src\Foo.cs
                   ↑ 一致しないので「ソースが見つかりません」

補足(最新化 / 現在の解): この問題は、現在は次の 2 つで
ほぼ解消できる。

手段 内容
Source Link PDB にソースの URL(GitHub 等)を埋め込む。デバッガが自動で取得する
DeterministicSourcePaths ビルド時にパスを /_/ のような相対表現へ正規化する
<PropertyGroup>
  <PublishRepositoryUrl>true</PublishRepositoryUrl>
  <EmbedUntrackedSources>true</EmbedUntrackedSources>
  <ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>
<ItemGroup>
  <PackageReference Include="Microsoft.SourceLink.GitHub" Version="..." PrivateAssets="All" />
</ItemGroup>

ContinuousIntegrationBuild を有効にすると
決定論的ビルド(同じ入力なら同じ出力)になり、
ソース パスも正規化されるため、
本ページが扱う「パスを一致させる」作業自体が不要になる。
以下は、それ以前の(あるいは Source Link が使えない)場合の手順である。

PDB とデバッガ

概要

  • シンボル ファイルとも呼ばれるプログラム データベース (.pdb) ファイル

    • ソース ファイルの識別子を、実行可能ファイルで使用される識別子に対応付ける。
    • ソース コード内のステートメントを実行可能ファイル内の実行命令に対応付ける。
  • デバッガはこの情報を使用して以下の 2 つを決定する。

    • Visual Studio IDE に表示されるソース ファイルと行番号。
    • 設定されたブレークポイントによって実行可能ファイル内で停止する位置。
  • また、シンボル ファイルには以下が格納されている。

    • ソース ファイルの元の場所、
    • および必要に応じてソース ファイルを取得できる「ソース サーバ」の場所

シンボル ファイルの検索パス

[ツール] → [オプション] → [デバッグ] → [シンボル] で、
シンボル ファイルの検索パスと「シンボル サーバ」を指定できる。

  • [シンボル ファイル (.pdb) の場所] に URL またはディレクトリ パスを入力

  • [このディレクトリにシンボルをキャッシュ] にディレクトリ パスを入力

  • 次のシンボルを自動的に読み込む

    • [除外されていないすべてのモジュール] オプション - [除外されるモジュールの指定] リンク
    • [指定したモジュールのみ] オプション - [モジュールの指定] リンク
  • [起動時にシンボルが見つからないとき警告 (ネイティブのみ)]

  • [DLL エクスポートを読み込む]

ソース ファイルの検索順

  • Visual Studio が以下の順序で、ソース ファイルを検索して解決するもよう。

    1. デバッガーを実行している Visual Studio インスタンスの IDE (devenv.exe) が開いているファイル
    2. Visual Studio インスタンスで開いているソリューション内のファイル
    3. Visual Studio ソリューションの [共通プロパティ] - [デバッグ ソース ファイル] ページで指定したディレクトリ。
    4. モジュールの *.pdb ファイル に含まれるソース情報。
  • 場合によって、

    • ソース サーバ」へのコマンド
    • モジュールがビルドされたソース ファイルの場所

    を検索する。

    • なお、ここでファイルが見つからなかった場合、

      • ..\ に遡りながらファイルを探し、
      • 見つからなかった場合、ファイルが見つからない旨のページを表示し、
        手動での指定が求められる。
    • ファイルが検索された場合は、そのフォルダのパスが自動的に
      [デバッグ ソース ファイル] へ追加される。

  • [デバッグ ソース ファイル] で指定したフォルダ以下に、
    ビルド サーバと同じフォルダ構成でソース ファイルが配置されていれば、
    以降、デバッグ時に、問題なくソース ファイルの参照が可能になる。

補足(この「検索順」の理解が要点): 原文の調査結果である
**「..\ に遡りながら探す」**という挙動が、
冒頭の結論(フォルダ構成さえ合っていればよい)の根拠になっている。

PDB のパス   : C:\build\src\Api\Foo.cs
指定フォルダ : D:\work
               → D:\work\src\Api\Foo.cs を試す
               → D:\work\Api\Foo.cs を試す
               → D:\work\Foo.cs を試す

つまり絶対パスの前半(ドライブやルート)が違っても、
後半のフォルダ構成が一致していれば解決できる

したがって「ビルド サーバとまったく同じパスに配置する」必要はない、
というのが原文の結論である。

サーバとデバッガ

ソース サーバ

概要

symsrv プロトコルを実装する「ソース サーバ」からソース ファイルをダウンロードできる。

有効化

「ソース サーバ」の使用を有効にするには、

  • [ツール] → [オプション] → [デバッグ] → [全般]
    • [マイ コードのみを有効にする] のチェックを外す。
    • [.NET Framework ソースのステッピングを有効にする] のチェックを外す。
    • [ソース サーバー サポートを有効にする] のチェックを入れ、
      以下の子オプションを選択する(省略可能)。
      • [ソース サーバー診断メッセージを出力ウィンドウに表示する]
      • [部分信頼アセンブリのソース サーバーを許可する (マネージのみ)]
      • [信頼されていないソース サーバー コマンドを常に確認なしで実行する]

補足: 現在は [Source Link のサポートを有効にする] という
項目が加わっており、こちらが実質の後継である。
「マイ コードのみを有効にする」を外す必要がある点は同じ
(自分のコード以外のステップ インを許可するため)。

シンボル サーバ

概要

  • symsrv プロトコルを実装する「シンボル サーバ」から
    シンボル ファイル(PDB)をダウンロードできる。

  • このシンボル ファイル(PDB)には任意のコマンドを埋め込むことができる。

    • このコマンドは、セキュリティ リスク的な観点から、制限できる。
      • srcsrv.ini というファイルに許可する(≒実行する)コマンドを列挙し、
        srcsrv.dll および devenv.exe と同じディレクトリに配置する。
      • srcsrv.ini ファイルにないコマンドを実行しようとすると、
        確認のダイアログ ボックスが表示される。

有効化

「シンボル サーバ」の使用を有効にするには、

  • [ツール] → [オプション] → [デバッグ] → [シンボル]
    → [シンボル ファイル (.pdb) の場所] で「シンボル サーバ」の URL を指定する。

  • なお、「ソース サーバ」の場所は、
    「シンボル ファイル (.pdb)」に含まれている。

補足(セキュリティ上の注意): 「PDB に任意のコマンドを埋め込める」
という指摘は重要である。
信頼できない PDB を読み込むと任意コマンドが実行され得るため、

  • [信頼されていないソース サーバー コマンドを常に確認なしで実行する] は
    有効にしない
  • シンボル サーバは信頼できる場所のみを指定する
    (Microsoft Symbol Server、社内サーバ、NuGet の公式)、

のが原則。

補足(代表的なシンボル サーバ):

用途 URL
Microsoft の公式 https://msdl.microsoft.com/download/symbols
NuGet.org.snupkg https://symbols.nuget.org/download/symbols
社内 ファイル共有 or Azure Artifacts

トラブルシュート

デバッグできない場合

現象

以下のように、

  • ステップ・インする際に、

    「ソースファイルがモジュールがビルドされたときのものと異なります。
    デバッガでこのファイルを使用しますか?」

  • ブレーク・ポイントを設定した際に、

    「ブレークポイントは、現在の設定ではヒットしません。
    ソースコードが元のバージョンと異なります。」

というメッセージが表示されデバッグできない場合がある。

対策

  • この現象は、

    • Visual Studio Debugger はソースファイルのハッシュを PDB のものと比較しており、
    • ソースファイルの内容が異なってることを検出することができるため、発生する。
  • この場合、

    • ソースファイルがモジュールがビルドされたときのものと異なります。
      デバッガでこのファイルを使用しますか?
      https://visual-studio-professional.com/source-file-module-build

      [ツール] → [オプション] → [デバッグ] → [全般] の順にクリックし、
      [元のバージョンと完全に一致するソース ファイルを必要とする] チェック ボックスをオフにする。

    • の手順に従って、ハッシュ値の一致を無視したデバッグ実行が可能な設定に変更することができる。

補足(この設定を外すことの意味): ハッシュ検証を無効にすると、
表示されているコードと実際に動いているコードがずれる可能性がある。
「ブレークポイントが変な行で止まる」「変数の値が合わない」といった
混乱の原因になるため、恒久的な設定にはしない方がよい。

本来の対処は、

  • バイナリと同じコミットのソースをチェックアウトする
  • 改行コードや BOM の差を無くす(Git の core.autocrlf に注意)、

である。特に改行コードの差だけでハッシュが変わるため、
「見た目は同じなのに一致しない」場合はこれを疑う。

[デバッグ ソース ファイル] の保存場所

設定のクリア

下記を削除するか、保存場所のソース ファイル自体を削除する。

保存場所

  • ソリューションの [共通プロパティ] - [デバッグ ソース ファイル] は、
    ソリューションのプロパティに追加され .suo ファイルに記録される。

  • ソースを選択するダイアログ(コモン コントロール)で
    最後に選択されたフォルダーが以下のレジストリに記憶される。

    • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\LastVisitedPidlMRULegacy
    • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU

    ※ Visual Studio はコモン コントロールをフックするので、
      .suo ファイルを消しても、[デバッグ ソース ファイル] の設定が
      復活することがある。

  • IDE で同一のソース ファイルが開かれている場合、そのファイルが利用される。

補足: 「.suo を消しても設定が復活する」という現象の原因を
**レジストリの MRU(最近使った場所)**にまで特定している点が、
本ページの調査の価値である。
.suo.vs フォルダ配下(VS2015 以降)にあり、
.gitignore に含めるのが標準なので、
チームで共有される設定ではない点にも注意。

参考

Microsoft Learn


Tags: 移行, .NET開発

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally