IIS のワーカプロセス上に存在するアプリケーションドメインの情報を取得する

Debugging Tools for Windowsを使用して、IIS のワーカプロセス上に存在するアプリケーションドメインの情報を取得する方法。

Debugging Tools for Windows のインストール

- Windows 用デバッグ ツール : 概要
http://www.microsoft.com/japan/whdc/DevTools/Debugging/default.mspx
上記サイトより、利用しているOSに合う Debugging Tools for Windows をダウンロードしてインストールする。
サイト中の下記リンクよりダウンロードが可能。
・Debugging Tools for Windows 32 ビット バージョンのインストール
・Debugging Tools for Windows 64 ビット バージョンのインストール
本パッケージに含まれるWinDbg を用いて AppDomain の情報を取得する。

シンボルパスの設定

WinDbg を使用するにあたって、まずはシンボルパスの設定を行う必要がある。
以下の手順でシンボルパスの設定を行う。
1. windbg.exe を起動する。 (デフォルトの設定でインストールした場合、 C:\Program Files\Debugging Tools for Windows\ にある。)
2. [File] メニューより [Symbol File Path] を選択する。 [Symbol Search Path] ダイアログが開く。
3. 開いたダイアログの Symbol path テキストボックスに、以下のように記入する。
SRV*<ダウンストリーム ストア>*http://msdl.microsoft.com/download/symbols
以下の手順を実施するにはMSのサイトで公開しているシンボルが必要となるが、上記ダウンストリーム ストア は、MSのサイトよりシンボルを自動的にダウンロードしキャッシュするフォルダとなる。ここには、自分が書き込み権限を持つ任意のフォルダを指定する。
たとえば、 C:\symbols をダウンストリームストアにする場合、以下のようになる。

SRV*C:\symbols*http://msdl.microsoft.com/download/symbols

- デバッグ ツールとシンボル : はじめに
http://www.microsoft.com/japan/whdc/DevTools/Debugging/debugstart.mspx

w3wp.exe の起動

ASP.NET アプリケーションを起動し、w3wp.exe を起動する。
タスクマネージャから w3wp.exe の PID を確認する。
w3wp.exe がタスクマネージャに現れない場合、実行ユーザごとのフィルタリングが行われている可能性がある。
その場合、 [すべてのユーザーのプロセスを表示] ボタンより、全ユーザのプロセスを表示する。

windbg によるプロセス中の AppDomain 情報の取得

管理者権限でコマンドプロンプトを起動する。
Debugging Tools for Windows のインストール先フォルダへ移動する。
(デフォルトでは C:\Program Files\Debugging Tools for Windowsにある)
以下のコマンドを実行する。

windbg.exe -c ".logopen <logfilename>;.loadby sos mscorwks;!dumpdomain;qd" -p <PID>

<logfilename> にはログファイルの出力先を、 <PID> には、情報を取得したいプロセスの PID を指定する。
今回の場合、 <PID> の部分には w3wp.exe の PID が入ることになる。
たとえば、 PID 1234 のプロセスの AppDomain の情報を c:\log.txt に出力する場合、以下のコマンドになる。

windbg.exe -c ".logopen c:\log.txt;.loadby sos mscorwks;!dumpdomain;qd" -p 1234

以上で、 windbg を用いて、プロセス中に含まれる AppDomain の情報を取得可能。
AppDomain の情報は、上記コマンドで指定した log.txt から確認できる。
その確認方法は以下の通り。

出力結果について

上記コマンドで出力した結果はテキストデータとして指定したパスに保存されている。
当該ファイルをテキストエディタにて開き、下記 2 行に該当する行を探す。

--------------------------------------
Domain <num>:
(<num> には 1 から始まりプロセス中に存在する AppDomain の数までの通し番号が入る。)

出力結果には、上記 2 行を区切りとしてプロセス中に含まれる AppDomain の情報が列挙されている。
この情報より、 AppDomain の存在有無について確認する。

出力結果例

--------------------------------------
Domain 4: 0ecc01a0
LowFrequencyHeap: 0ecc01c4
HighFrequencyHeap: 0ecc0210
StubHeap: 0ecc025c
Stage: OPEN
SecurityDescriptor: 016df778
Name: MyAppDomain_B
(以下、ロードされているアセンブリについての情報が続く)

補足

今回は、SOS デバッガ拡張に含まれている、 DumpDomain コマンドを用いることで、プロセス中の AppDomain の情報を取得した。
SOS デバッガ拡張の詳細は、以下のドキュメントを参照。
- SOS デバッガ拡張 (SOS.dll)
http://msdn.microsoft.com/ja-jp/library/bb190764.aspx

コンソールでのルートの解明

script/consoleでルート設定を確認する方法。

$ ./script/console 
Loading development environment (Rails 2.3.2)
>> irb ActionController::Routing::Routes # irbをirbから実行することにより、デフォルトオブジェクト(self)をルートセットに設定する。(コマンドを実行するときの入力の手間が省ける。)
>> generate(:controller => "posts", :action => "show", :id => "1")  # 生成
=> "/posts/1"
>> recognize_path("/") # 認識
=> {:action=>"index", :controller=>"top"}
>> recognize_path("/posts", :method => :get)
=> {:action=>"index", :controller=>"posts"}
>> recognize_path("/posts", :method => :post)
=> {:action=>"create", :controller=>"posts"}

script/consoleで名前付きルートの解明

※ Rails3以降では、
include Rails.application.routes.url_helpers

>> include ActionController::UrlWriter # 名前付きルートをテストするためにインクルード
=> Object
>> login_path
=> "/login"
>> default_url_options[:host] = "example.com" # _urlでエラーにならないようデフォルトのホスト値を設定
=> "example.com"
>> login_url
=> "http://example.com/login"
>> ActionController::Routing::Routes.recognize_path(login_path)
=> {:action=>"new", :controller=>"sessions"}

emacsにナビゲーションペインを追加する「emacs-nav」

emacs-nav - Google Code
emacsにファイル・フォルダブラウズするペインを追加する。
使い方(nav.elのコメントから抜粋)

;; To use this file, put something like the following in your
;; ~/.emacs:
;;
;; (add-to-list 'load-path "/directory/containing/nav/")
;; (require 'nav)
;;
;; Type M-x nav to open the navigation window. It should show up as a
;; 30-character wide column on the left, showing the contents of the
;; current directory. If there are multiple windows open, all but one
;; will be closed to make sure the nav window shows up correctly.
;;; Key Bindings
;;
;;   Enter/Return: Open file or directory under cursor.
;;
;;   1: Open file under cursor in 1st other window.
;;   2: Open file under cursor in 2nd other window.
;;
;;   c: Copy file or directory under cursor.
;;   d: Delete file or directory under cursor (asks to confirm first).
;;   e: Edit current directory in dired.
;;   f: Recursively find files whose names or contents match some regexp.
;;   g: Recursively grep for some regexp.
;;   j: Jump to another directory.
;;   m: Move or rename file or directory.
;;   n: Make new directory.
;;   p: Pop directory stack to go back to the directory where you just were.
;;   q: Quit nav.
;;   r: Refresh.
;;   s: Start a shell in an emacs window in the current directory.
;;   t: Start a terminal in an emacs window in the current directory.
;;      This allows programs like vi and less to run. Exit with C-d C-d.
;;   u: Go up to parent directory.
;;   !: Run shell command.
;;   [: Rotate non-nav windows counter clockwise.
;;   ]: Rotate non-nav windows clockwise.
;;
;;   :: Go into debug mode (should only be needed if you are hacking nav.el).

Mantisの変更履歴(Change Log)を表示する

「システム管理」>「プロジェクト管理」でプロジェクトを選択して、「バージョン」を登録する。
すると、チケット登録で「製品バージョン」を選択できるようになる。
そして、そのチケットのステータス更新時(解決済みにしたり完了するとき)の画面で、「修正済みバージョン」を選択できるようになる。
検索結果や印刷画面、CSV出力では、以下のようにconfig_inc.phpで、表示するカラムを設定する変数に、'fixed_in_version'を追加すれば、表示されるようになる。

<?php
...
$g_view_issues_page_columns = array ( 'selection', 'edit', 'priority', 'id', 'reporter_id', 'sponsorship_total', 'bugnotes_count', 'attachment', 'category', 'severity', 'status', 'fixed_in_version', 'last_updated', 'summary' );
$g_print_issues_page_columns = array ( 'selection', 'priority', 'id', 'reporter_id', 'sponsorship_total', 'bugnotes_count', 'attachment', 'category', 'severity', 'status', 'fixed_in_version', 'last_updated',  'summary' );
$g_csv_columns = array ( 'id', 'project_id', 'reporter_id', 'handler_id', 'priority', 'severity', 'reproducibility', 'version', 'projection', 'category', 'date_submitted', 'eta', 'os', 'os_build', 'platform', 'view_state', 'last_updated', 'summary', 'status', 'resolution', 'fixed_in_version', 'duplicate_id' );
...