Insider's Eye

Visual Studio 2008で見る.NET Frameworkのソースコード

デジタルアドバンテージ 遠藤 孝信
2008/02/22


 昨年10月、「MS、.NETのソースコードを公開へ」というニュースが流れたが、そこでのアナウンスどおり、先日より.NET Frameworkクラス・ライブラリのソースコード公開が開始されている。

 ただし現時点ではソースコードの公開といっても、ZIP形式でまとめられたソース・ファイルがダウンロード可能、といった公開方法ではなく、先日発売となったVisual Studio 2008(Express Editionは除く)でデバッガを使用する際に、クラス・ライブラリのメソッド内部までソースコード・レベルでのトレース(ステップ・イン実行)が可能になるというものだ。

 もともとVisual Studioには、ソースコードが納められた(通常は自社内の)サーバに接続し、トレース時に手元にある実行ファイルやDLLファイルのソースコードを表示するという機能が搭載されているが、今回のケースではマイクロソフトが運用しているソースコード・サーバに接続してこの機能を使うことになる。つまり必要に応じてサーバからソースコードがダウンロードされ、表示されるというわけだ。

 なお、一度ダウンロードされたソースコードは指定したディレクトリにキャッシュされるのだが、後で紹介しているように、すべてのソースコードをあらかじめキャッシュにダウンロードするツールもすでに公開されている。このツールを使えば、ネットワークにアクセスすることなくソースコードをトレースできるし、テキスト・エディタで端からじっくりソースコードを読んでいくことも可能だ。

 ではVisual Studio 2008を使用して、実際に.NET Frameworkクラス・ライブラリのソースコードを追いかけてみよう。

ソースコードを表示するための設定

 以下ではまず、Visual Studio 2008でクラス・ライブラリのソースコードを表示するための設定方法についてまとめておく(以下ではVisual Studio 2008 Professional EditionをWindows XP上で使用している)。

 最初にメニューから[ツール]−[オプション]を実行して、[オプション]ダイアログを開く。そして左側のツリーから[デバッグ]−[全般]を選択し、以下の図1に示す2カ所の設定を変更する。


図1 [オプション]ダイアログの「全般」
Visual Studio 2008のメニューから[ツール]−[オプション]を実行して開く。
  [デバッグ]−[全般]を選択する。
  [‘マイコードのみ’設定を有効にする]のチェックをはずす。これによりライブラリのコードもトレースできるようになる。「マイコード」とは開発者が自分で記述したコードのことである。
  [ソース サーバー サポートを有効にする]をチェックする。

 続いて、今度は左側のツリーで[デバッグ]−[シンボル]を選択し、以下の図2に示す3カ所の設定を行う。


図2 [オプション]ダイアログの「シンボル」
  [デバッグ]−[シンボル]を選択する。
  「http://referencesource.microsoft.com/symbols」を入力する。入力には右上のフォルダマークのボタンをクリックする。
  ダウンロードしたシンボル・ファイルやソースコードをキャッシュするディレクトリを指定する。任意のディレクトリでよい。
  [シンボルが手動で読み込まれるときのみ上記の場所を探す]のチェックをはずす。

 シンボル・ファイル(pdb)とは、拡張子が「.pdb」のファイルであり*1、これにはバイナリとソースコードを対応付けるための情報が格納されている。このため厳密には、まずシンボル・ファイルがダウンロードされ、その情報を基にソースコードがダウンロードされて、上記ダイアログの で指定したディレクトリに保存されることになる。

*1 pdbは「Program Database」の略

 また、上記ダイアログで のチェックが必要な理由は、自動でシンボルを(マイクロソフトのサーバから)読み込ませる設定にすると、デバッグ実行開始時に非常に時間がかかるためだ。

 以上でソースコードを表示されるための設定は完了である。

クラス・ライブラリのソースコードにステップ・イン

 では実際にクラス・ライブラリのソースコードを表示させてみよう。

 ここでは簡単な例としてVisual BasicでWindowsアプリケーションのプロジェクトを新規作成し、フォームをダブルクリックしてから、次のようなコードを1行書き込む。


図3 「Me.BackColor = Color.Brown」を追加

 単にフォームの背景色を設定しているだけである。ここでは例として、このFormクラスのBackColorプロパティのソースコードを確認してみよう。

 まず[F9]キーを押すなどして、この行にブレイクポイントを設定する。


図4 ブレイクポイントを設定

 そして[F5]キーを押してデバッグ実行を開始する。もちろん、この行で実行は中断するが、この状態で、メニューの[デバッグ]−[ウィンドウ]−[モジュール]を実行して、[モジュール]ウィンドウを表示する。


図5 実行の中断中に[モジュール]ウィンドウを表示
[モジュール]ウィンドウはメニューの[デバッグ]−[ウィンドウ]−[モジュール]により開く。

 この[モジュール]ウィンドウは、アプリケーションの実行に際してメモリに読み込まれたアセンブリの一覧を表示している。当然ながら、Formクラスが含まれているアセンブリである「System.Windows.Forms.dll」も一覧に含まれているが、「シンボルの状態」の列を見ると「PDBファイルを開けないか、ファイルが見つかりません。」となっているのが分かる。

 ここで次の図6のように、このSystem.Windows.Forms.dllの行を右クリックし、コンテキスト・メニューより[シンボルの読み込み]を実行する。これにより、マイクロソフトのサーバからシンボル・ファイルがまずダウンロードされる。


図6 「シンボルの読み込み」を実行

 初回時のシンボルの読み込みにはダウンロードに若干時間がかかり、その間、IDEがフリーズしてしまうが、ダウンロードが終わると、「シンボルの状態」の列は「シンボルが読み込まれました」という表示に変わる。

 ではいよいよ、[F11]キーを押してステップ・インしてみよう。


図7 表示されたFormクラスのソースコード

 Form.csが開かれ、BackColorプロパティ定義部分が表示された。コードがC#なのは、このソースコードがもともとC#で記述されているからだ*2

*2 さすがにVB専用のライブラリ(Microsoft.VisualBasic名前空間のクラスなど)はVisual Basicで記述されているが、それ以外はすべてC#で記述されているようである。

 この時点で、キャッシュとして指定したディレクトリ(図2の設定では「c:\symbols」)には、ダウンロードされた「System.Windows.Forms.pdb」と「Form.cs」を見つけることができる。ちなみに、Form.csはサイズが344KBytesだが、System.Windows.Forms.pdbの方は約10MBytesのファイルである。次回にSystem.Windows.Forms.dllのシンボルを読み込む場合には、このキャッシュされたファイルが利用される。

 図7の黄色部分のコードは「base.」によりFormクラスの親クラスであるControlクラスのBackColorプロパティにアクセスしている。このため、さらに[F11]キーを押してステップ・インを継続すると、今度はControl.csがダウンロードされ、エディタで開かれる。


図8 表示されたControlクラスのソースコード

 以上のようにして、順次ダウンロードしながらソースコードをトレースしていくことができるようになっている。

ソースコードの一括ダウンロード

 一度読み込ませれば、シンボルやソース・ファイルはすべてキャッシュされていくのだが、Visual Studio 2008を使わずに、事前に一括してキャッシュを作成するツール「.NET Mass Downloader」が以下のページでオープンソースとして公開されている。

CodePlex内の.NET Mass Downloaderのホームページ


図9 .NET Mass Downloaderのホームページ

 このページの右上端にある「Current Release」の部分のリンクからコンパイル済みの実行ファイルをダウンロード可能だ。

 この.NET Mass Downloaderはコンソール・アプリケーションであるため、コマンド・プロンプトから実行する。いくつかのオプションが用意されているが、以下のように「-d」オプションを指定して実行すれば、そのディレクトリに存在するアセンブリ(EXEファイルやDLLファイル)に対応したシンボル・ファイルとソースコードが、Visual Studio 2008で設定したキャッシュ・ディレクトリにどんどんダウンロードされていく*3

NetMassDownloader -d C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727

*3 「-d」オプションでは、指定されたディレクトリにあるすべてのEXEファイルやDLLファイルについてダウンロードを行おうとするため、サーバにシンボルが存在しないものについてはエラーが表示される。

 v2.0.50727のディレクトリは.NET Framework 2.0のクラス・ライブラリが納められているディレクトリである。筆者の環境では、このコマンドが完全に終了するまでに20分ほどかかった。

 あらかじめこのようにしてキャッシュを構築しておけば、図2 の[シンボルが手動で読み込まれるときのみ上記の場所を探す]のチェックをオフにして自動的にシンボルを読み込ませるようにしても、デバッガの起動は遅くならない。

 マイクロソフトはクラス・ライブラリの難読化を一切行っておらず、「.NET逆コンパイラとコードを難読化するDotfuscator」でも紹介しているReflectorを使えば、これまでにも.NET Frameworkのクラス・ライブラリを逆コンパイルして、そのソースコードをのぞき見ることができた。

 しかし、公開されたソースコードには(もちろん英語だが)多くのコメントが入っており、ローカル変数名も元のままの“生”のソースコードである。そしてそれがVisual Studio 2008でシームレスにトレースできるようになるというのは開発者にとって非常に価値のあることであり、さまざまな面で大いに役立てることができると思われる。End of Article

 Insider's Eye


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間