Windows デバッガーを使用したマネージド コードのデバッグ

Windows デバッガー (WinDbg、CDB、および NTSD) を使用して、マネージド コードを含むターゲット アプリケーションをデバッグできます。 マネージド コードをデバッグするには、SOS デバッグ拡張機能 (sos.dll) とデータ アクセス コンポーネント (mscordacwks.dll) を読み込む必要があります。

Windows デバッガーは、Visual Studio デバッガーとは別です。 Windows デバッガーと Visual Studio デバッガーの違いについては、「Windows デバッグ」を参照してください。

マネージド コードの概要

マネージド コードは、Microsoft .NET 共通言語ランタイム (CLR) と共に実行されます。 マネージド コード アプリケーションでは、コンパイラによって生成されるバイナリ コードは、プラットフォームに依存しない Microsoft Intermediate Language (MSIL) になります。

マネージド コードが実行されると、ランタイムがプラットフォーム固有のネイティブ コードを生成します。 MSIL からネイティブ コードを生成するプロセスは、Just-In-Time (JIT) コンパイルと呼ばれます。 JIT コンパイラが特定のメソッドの MSIL をコンパイルした後、メソッドのネイティブ コードがメモリ内に残ります。 後でこのメソッドが呼び出されるたびに、ネイティブ コードが実行され、JIT コンパイラが関与する必要はありません。

マネージド コードは、さまざまなソフトウェア プロデューサーによって製造された複数のコンパイラを使用してビルドできます。 特に、Microsoft Visual Studio では、マネージド拡張機能を使用して、C#、Visual Basic、JScript、C++ など、いくつかの異なる言語からマネージド コードをビルドできます。

CLR は、.NET Framework が更新されるたびに更新されるわけではありません。 たとえば、.NET Framework のバージョン 2.0、3.0、および 3.5 はすべて、CLR のバージョン 2.0 を使用します。 下表に、.NET Framework の各バージョンで使用される CLR のバージョンとファイル名を示します。

.NET Framework のバージョン CLR バージョン CLR ファイル名
1.1 1.1 mscorwks.dll
2.0 2.0 mscorwks.dll
3.0 2.0 mscorwks.dll
3.5 2.0 mscorwks.dll
4.0 4.0 clr.dll
4.5 4.0 clr.dll

マネージド コードをデバッグする

マネージド コードをデバッグするには、デバッガーで以下の 2 つのコンポーネントを読み込む必要があります。

.NET Framework のすべてのバージョンで、DAC のファイル名は mscordacwks.dll、SOS デバッグ拡張機能のファイル名は sos.dll です。

SOS デバッグ拡張機能 (sos.dll) の取得

SOS デバッグ拡張機能 (sos.dll) ファイルは、Windows 用デバッグ ツールの現在のバージョンには含まれていません。

.NET Framework バージョン 2.0 以降の場合、sos.dll は .NET Framework のインストールに含まれています。

.NET Framework のバージョン 1.x の場合、sos.dll は .NET Framework のインストールに含まれていません。 .NET Framework 1.x 用の sos.dll を取得するには、Windows 7 の Windows 用デバッグ ツールの 32 ビット バージョンをダウンロードします。

Windows 7 の Windows 用デバッグ ツールは、Windows SDK for Windows 7 に含まれています。これは以下の 2 つの場所で入手できます。

x64 バージョンの Windows を実行している場合は、ISO を使用して、32 ビット バージョンの SDK を指定できるようにします。 Sos.dllは、Windows 7 の Windows 用デバッグ ツールの 32 ビット バージョンにのみ含まれています。

mscordacwks.dll と sos.dll の読み込み (ライブ デバッグ)

デバッガーとデバッグ対象のアプリケーションが、同じコンピューター上で実行されているとします。 その後、アプリケーションで使用される .NET Framework がコンピューターにインストールされ、デバッガーで使用できるようになります。

デバッガーは、マネージド コード アプリケーションが使用している CLR のバージョンと同じバージョンの DAC を読み込む必要があります。 ビット数 (32 ビットまたは 64 ビット) も一致している必要があります。 DAC (mscordacwks.dll) には .NET Framework が付属しています。 正しいバージョンの DAC を読み込むには、マネージド コード アプリケーションにデバッガーをアタッチし、次のコマンドを入力します。

.cordll -ve -u -l

出力は以下のようなものになります。

CLRDLL: Loaded DLL C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscordacwks.dll
CLR DLL status: Loaded DLL C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscordacwks.dll

mscordacwks.dll のバージョンが、アプリケーションが使用している CLR のバージョンと一致していることを確認するには、次のいずれかのコマンドを入力して、読み込まれた CLR モジュールに関する情報を表示します。

lmv mclr (CLR のバージョン 4.0 用)

lmv mscorwks (CLR のバージョン 1.0 または 2.0 用)

出力は以下のようなものになります。

start             end                 module name
000007ff`26710000 000007ff`2706e000   clr        (deferred)             
    Image path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
...

上の例では、CLR (clr.dll) のバージョンが DAC (mscordacwks.dll) のバージョン、v4.0.30319 と一致しています。 また、両方のコンポーネントは 64 ビットです。

.cordll を使用して DAC を読み込むと、SOS デバッグ拡張機能 (sos.dll) が自動的に読み込まれる場合があります。 sos.dll が自動的に読み込まれない場合は、次のいずれかのコマンドを使用して読み込むことができます。

.loadby sos clr (CLR のバージョン 4.0 用)

.loadby sos mscorwks (CLR のバージョン 1.0 または 2.0 用)

.loadby を使用する代わりに、.load を使用できます。 たとえば、64 ビット CLR のバージョン 4.0 を読み込むには、次のようなコマンドを入力します。

.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll

上記の出力では、SOS デバッグ拡張機能 (sos.dll) のバージョンが CLR と DAC のバージョン、v4.0.30319 と一致しています。 また、3 つのコンポーネントはすべて 64 ビットです。

mscordacwks.dll と sos.dll の読み込み (ダンプ ファイル)

デバッガーを使用して、別のコンピューターで作成された (マネージド コード アプリケーションの) ダンプ ファイルを開くとします。

デバッガーは、マネージド コード アプリケーションが別のコンピューターで使用していた CLR のバージョンと同じバージョンの DAC を読み込む必要があります。 ビット数 (32 ビットまたは 64 ビット) も一致している必要があります。

DAC (mscordacwks.dll) には .NET Framework が付属していますが、デバッガーを実行しているコンピューターに正しいバージョンの .NET Framework がインストールされていないものとします。 3 つのオプションがあります。

  • シンボル サーバーから DAC を読み込みます。 たとえば、シンボル パスに Microsoft のパブリック シンボル サーバーを含めることができます。
  • デバッガーを実行しているコンピューターに、正しいバージョンの .NET Framework をインストールします。
  • ダンプ ファイルを作成したユーザー (別のコンピューター) から適切なバージョンの mscordacwks.dll を取得し、デバッガーを実行しているコンピューターに手動でコピーします。

ここで、Microsoft のパブリック シンボル サーバーの使用状況を示します。

次のコマンドを入力します。

.sympath+ srv\* (シンボル サーバーをシンボル パスに追加する)。

!sym noisy

.cordll -ve -u -l

出力は次のようなものになります。

CLRDLL: Unable to get version info for 'C:\Windows\Microsoft.NET
   \Framework64\v4.0.30319\mscordacwks.dll', Win32 error 0n87

SYMSRV:  C:\ProgramData\dbg\sym\mscordacwks_AMD64_AMD64_4.0.30319.18010.dll
   \5038768C95e000\mscordacwks_AMD64_AMD64_4.0.30319.18010.dll not found

SYMSRV:  mscordacwks_AMD64_AMD64_4.0.30319.18010.dll from 
   https://msdl.microsoft.com/download/symbols: 570542 bytes - copied         
...
SYMSRV:  C:\ProgramData\dbg\sym\SOS_AMD64_AMD64_4.0.30319.18010.dll
   \5038768C95e000\SOS_AMD64_AMD64_4.0.30319.18010.dll not found

SYMSRV:  SOS_AMD64_AMD64_4.0.30319.18010.dll from 
   https://msdl.microsoft.com/download/symbols: 297048 bytes - copied         
...
Automatically loaded SOS Extension
...

上の出力では、デバッガーが最初にローカル コンピューターの C:\Windows\Microsoft.NET およびシンボル キャッシュ (C:\ProgramData\dbg\sym) 内で、mscordacwks.dll と sos.dll を検索したことがわかります。 デバッガーは、ローカル コンピューターで正しいバージョンのファイルのを見つけられなかったとき、パブリック シンボル サーバーからファイルを取得しました。

mscordacwks.dll のバージョンが、アプリケーションが使用していた CLR のバージョンと一致していることを確認するには、次のいずれかのコマンドを入力して、読み込まれた CLR モジュールに関する情報を表示します。

lmv -mclr (CLR のバージョン 4.0 用)

lmv -mscorwks (CLR のバージョン 1.0 または 2.0 用)

出力は以下のようなものになります。

start             end                 module name
000007ff`26710000 000007ff`2706e000   clr        (deferred)             
    Image path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
...

上の例では、CLR (clr.dll) のバージョンが DAC (mscordacwks.dll) の製品バージョン、v4.0.30319 と一致しています。 また、両方のコンポーネントは 64 ビットです。

SOS デバッグ拡張機能の使用

SOS デバッグ拡張機能が正しく読み込まれたことを確認するには、.chain コマンドを入力します。

0:000> .chain
Extension DLL search Path:
...
Extension DLL chain:
    C:\ProgramData\dbg\sym\SOS_AMD64_AMD64_4.0.30319.18010.dll\...
        ...
    dbghelp: image 6.13.0014.1665, API 6.2.6, built Wed Dec 12 03:02:43 2012
...

SOS デバッグ拡張機能をテストするには、「!sos.help」と入力します。 次に、SOS デバッグ拡張機能によって提供されるコマンドのいずれかを試します。 たとえば、!sos.DumpDomain または !sos.Threads コマンドを試すことができます。

メモ

マネージド コード アプリケーションが複数のバージョンの CLR を読み込むことがあります。 その場合は、読み込む DAC のバージョンを指定する必要があります。 詳細については、「.cordll」を参照してください。