-
Notifications
You must be signed in to change notification settings - Fork 0
MS_PDBSourcePath
- 戻る
-
一致が望ましいが、ビルド環境と開発環境のソースファイルパスが
一致しているケースは稀。 -
ビルド環境と開発環境のソースファイルパスを一致させる方法について調査した。
-
結論としては、[デバッグ ソース ファイル] に指定したフォルダ以下に
ビルド環境と構成を一致させたソースファイルが存在すれば問題ない。
補足(なぜパスが問題になるのか): 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) ファイル
- ソース ファイルの識別子を、実行可能ファイルで使用される識別子に対応付ける。
- ソース コード内のステートメントを実行可能ファイル内の実行命令に対応付ける。
-
デバッガはこの情報を使用して以下の 2 つを決定する。
- Visual Studio IDE に表示されるソース ファイルと行番号。
- 設定されたブレークポイントによって実行可能ファイル内で停止する位置。
-
また、シンボル ファイルには以下が格納されている。
- ソース ファイルの元の場所、
- および必要に応じてソース ファイルを取得できる「ソース サーバ」の場所
[ツール] → [オプション] → [デバッグ] → [シンボル] で、
シンボル ファイルの検索パスと「シンボル サーバ」を指定できる。
-
[シンボル ファイル (.pdb) の場所] に URL またはディレクトリ パスを入力
-
[このディレクトリにシンボルをキャッシュ] にディレクトリ パスを入力
-
次のシンボルを自動的に読み込む
- [除外されていないすべてのモジュール] オプション - [除外されるモジュールの指定] リンク
- [指定したモジュールのみ] オプション - [モジュールの指定] リンク
-
[起動時にシンボルが見つからないとき警告 (ネイティブのみ)]
-
[DLL エクスポートを読み込む]
-
Visual Studio が以下の順序で、ソース ファイルを検索して解決するもよう。
- デバッガーを実行している Visual Studio インスタンスの IDE (devenv.exe) が開いているファイル
- Visual Studio インスタンスで開いているソリューション内のファイル
- Visual Studio ソリューションの [共通プロパティ] - [デバッグ ソース ファイル] ページで指定したディレクトリ。
- モジュールの
*.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 ファイルにないコマンドを実行しようとすると、
確認のダイアログ ボックスが表示される。
- srcsrv.ini というファイルに許可する(≒実行する)コマンドを列挙し、
- このコマンドは、セキュリティ リスク的な観点から、制限できる。
「シンボル サーバ」の使用を有効にするには、
-
[ツール] → [オプション] → [デバッグ] → [シンボル]
→ [シンボル ファイル (.pdb) の場所] で「シンボル サーバ」の URL を指定する。 -
なお、「ソース サーバ」の場所は、
「シンボル ファイル (.pdb)」に含まれている。
補足(セキュリティ上の注意): 「PDB に任意のコマンドを埋め込める」
という指摘は重要である。
信頼できない PDB を読み込むと任意コマンドが実行され得るため、
- [信頼されていないソース サーバー コマンドを常に確認なしで実行する] は
有効にしない、- シンボル サーバは信頼できる場所のみを指定する
(Microsoft Symbol Server、社内サーバ、NuGet の公式)、のが原則。
補足(代表的なシンボル サーバ):
用途 URL Microsoft の公式 https://msdl.microsoft.com/download/symbolsNuGet.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\LastVisitedPidlMRULegacyHKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU
※ Visual Studio はコモン コントロールをフックするので、
.suoファイルを消しても、[デバッグ ソース ファイル] の設定が
復活することがある。 -
IDE で同一のソース ファイルが開かれている場合、そのファイルが利用される。
補足: 「
.suoを消しても設定が復活する」という現象の原因を
**レジストリの MRU(最近使った場所)**にまで特定している点が、
本ページの調査の価値である。
.suoは.vsフォルダ配下(VS2015 以降)にあり、
.gitignoreに含めるのが標準なので、
チームで共有される設定ではない点にも注意。
-
シンボル (.pdb) ファイル、ソース ファイル、およびバイナリ ファイルの検索
https://learn.microsoft.com/ja-jp/visualstudio/debugger/specify-symbol-dot-pdb-and-source-files-in-the-visual-studio-debugger -
Specify symbol (.pdb) and source files in the debugger
https://learn.microsoft.com/en-us/visualstudio/debugger/specify-symbol-dot-pdb-and-source-files-in-the-visual-studio-debugger
- Source Link
https://learn.microsoft.com/ja-jp/dotnet/standard/library-guidance/sourcelink - 決定論的ビルド
https://learn.microsoft.com/ja-jp/dotnet/core/project-sdk/msbuild-props#continuousintegrationbuild
Tags: 移行, .NET開発
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。