tmori3y2のブログ

主にWindowsのプログラムなど

初めてのPull Request & ReactivePropertyへのステップインデバッグ

tmori3y2.hatenablog.com

予告通り、Pull Requestしました。

人生初です。

blog.okazuki.jp

職場でインストールして焦った

職場に行くとアップデートされていたので、アップデートすると、ソースファイルを寄越せと怒られる。

一瞬、

デバッグ情報は、pdbonlyじゃなくてfullでやらなきゃダメだったか?」

と思ったが、自宅でPull Requestした環境にはソースファイルはあったし、.pdbにはローカルのソースファイルパスが記録されるので、当たり前かと思い、githubからダウンロード。無事、ステップイン。

こりゃ、みんなから質問殺到するかもしれないので、慌ててかずき大先生のブログにコメント。

早速の対応ありがとうございました。

一つ大事なことを忘れてました。

自分でビルドした時は当たり前の様に、ソースコードを開けたので、うっかりしていました。

利用される方は、初回、ソースコードを要求されるので、githubから落としたソースコードを指定して下さい。

あと、MyCode以外のステップインを常時有効にすると、VSの起動が遅くなるので、必要に応じてということで。

ReactiveProperty v2.7.3.1のソースファイルはこちらから。

GitHub - runceel/ReactiveProperty at fcf5aedcf3a05fb359414e62876c0d55a797acf1

昔の記事の続き

tmori3y2.hatenablog.com

この時は、シンボルサーバから、Reactive Extensionsの.pdbをシンボルサーバから取ってきたものの、ソースファイルを取ってくることまで思い至らなかったこと、ReactivePropertyでステップインが途切れるので、深入りしなかったが、今回はつながったので、Reactive Extensionsのソースファイルも持ってくることにした。

GitHub - Reactive-Extensions/Rx.NET at v2.2.5

先ずは、F11でReactivePropertyにステップイン

初回にパスを聞かれるので、慌てずにダウンロードしたソースファイルがあるパスを指定。

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

と聞かれるので、そのままOK。

無事、ステップインした。

勿論、Releaseビルドで最適化されているので、ソースファイルを開いてステップイン出来なかったり、ブレークポイントを置けなかったりする。

その場合は、呼び出し履歴でソースファイルを開いたり、実行していない時に、一旦開いたソースファイルや、自分で開いたソースファイルでブレークポイントを置いたりすると、ブレーク出来る場合もある。

じゃあ、デバッグシンボルをfullで作成したらどうなのか?と思うかもしれないが、これはReleaseビルドでは非推奨となっているのでやってはイケない。

Releaseビルド + .pdb fileの意義は何なのか?

Debugビルドのfullデバッグ情報は、ソースファイルで実装した内容が最適化されていない状態で正しく動作することを、デバッガで実際に動かして確認するために使用される。

Releaseビルドの.pdb fileは、実運用環境の最適化されたコードにデバッガでアタッチしたり、実運用環境から回収したクラッシュダンプからクラッシュ箇所を特定したりする場合に使用される。

ここで重要なのは、実運用環境用アセンブリと共に.pdb fileが出荷されていることではない。

アセンブリと.pdb fileが同時に作成されていること」

ソースファイルは、ビルドに使用したものそのもので無くても構わないが、.pdbファイルは後から作成しても、アセンブリと共に使用することはできない。

大事なことを言います。

インストーラ用のビルドでは必ず.pdbファイルを出力するようにして、捨てないで保管しておいてください」

ソースファイルがモジュールがビルドされたときのものと異なっていてもデバッグ出来るの?

「どういうこと?」

.pdbファイルに記録されているのは、

  • ソースファイル中のステートメントとブレーク可能なバイナリコード位置との対応付け
  • シンボル情報
  • ビルドしたときのソースファイルのパス
  • ソースサーバの情報(あれば)

などがある。

シンボル (.pdb) ファイル、ソース ファイル、およびバイナリ ファイルの検索

デバッガに余計な制約がなければ、対応していない言語のソースファイルであっても、理屈上はステップ実行できる。

そうなると当然のことながら、C#6.0で開発されたNuGet PackageのデバッグをVS2013で行うなんて、お茶の子さいさいの朝飯前である。

ただし、その場合はデバッグが終わると、エディタが開かれているソースファイルに対して大量の構文エラーを吐き出すことになるのは言うまでもない。

.NET Frameworkのシンボルサーバやソースサーバは壊れている?

残念ながら、前回に引き続き、Reactive Extensionsは.pdbファイルこそダウンロード出来るものの、ソースファイルの場所すら聞いてこない。

というか、前回は出来ていた.NET Frameworkのソースファイルへのステップインすらできなくなっている。

よくよく考えてみると、

  • Target Frameworkのバージョン
  • 実際のOS環境にインストールされている.NET Framework 4.xのバージョン
  • Microsoftシンボルサーバの.pdbファイルのバージョン
  • Microsoftソースサーバのファイルのバージョン

の組み合わせがあるのに、シンボル設定をしてダウンロードされるファイルは、プロジェクト依存じゃなく一つ。

実行時にモジュールウィンドウを開いて、シンボルロード済みのアセンブリのバージョンをチェックしてみると、実際のOS環境にインストールされている.NET Framework 4.6.1と同じシンボルはロードされている。

本家USのMSDNフォーラムの情報からすると過去にも最新のソースが取得できないという書き込みがあり、現在は、まだソースサーバに.NET Framework 4.6.1は上がっていたのではないかと思われる。

また、いろいろな状況証拠からすると、.NET Framework系のソースサーバが立てられているアセンブリのソースは、ローカルにダウンロードしても使用できない。つまり、自分の実行環境の.NET Frameworkが最新の場合だと、Microsoftがその気になって、ソースをサーバにアップしないと、ステップインによるデバッグは出来ない。。。

MSDNサブスクリプションの有償サポート受けないとアップしてくれないのかな・・・?