Hyper-V 第二世代仮想マシンの Guest OS への windbg 接続方法
久方ぶりです。まさかたです。
さて、以前、「Hyper-Vなどの仮想OSにwindbgをアタッチする方法」で、仮想 OS 上の COM ポートに名前付きパイプを割り当てる方法をご案内いたしました。この方法は、現在もご利用いただけますが、Windows 8.1/Windows Server 2012 R2 より導入された Hyper-V 第二世代仮想マシンの Guest OS には、デフォルトでは以下のように COM ポートが見えない状態になっているため、戸惑われる方がいらっしゃるかと思います。
そこで、今回は、第二世代仮想マシンの Guest OS でも従来通り名前付きパイプを COM ポートに設定して、windbg でカーネルデバッグを行っていただくための方法をご紹介いたします。
その前に前提として、そもそも Hyper-V 第二世代仮想マシンとは、Hyper-V マネージャーで仮想マシンを新規作成する際に、以下のように選択した仮想マシンのことです。
以前の第一世代と比べて、エミュレーションするハードウェアを新しくしたからこそできるいくつかの特徴がありますが、詳細は、下記ドキュメントに譲ります。
Generation 2 Virtual Machine Overview
https://technet.microsoft.com/en-us/library/dn282285.aspx
ここでは、あくまでもカーネルデバッグの設定をする上で必要な話として、BIOS ベースのファームウェアではなく UEFI ベースとなってセキュアブートがデフォルトとなっていることや、サポートするゲスト OS が現時点では以下の 4 種類であることを記載しておきたいと思います。
・Windows Server 2012
・Windows Server 2012 R2
・Windows 8 (64 ビットのみ)
・Windows 8.1 (64 ビットのみ)
それでは、具体的な手順を説明します。
1. Hyper-V ( ホスト OS, Parent Partition) 側の設定
(1) 「Windows PowerShell 用 Hyper-V モジュール」の有効化
[コントロール パネル] から [Windows の機能の有効化または無効化]で、[Hyper-V]-[Hyper-V 管理ツール]を展開し、[Windows PowerShell 用 Hyper-V モジュール]にチェックが入っていることを確認します。
これが入っていないと、Hyper-V 管理用の PowerShell コマンドレットを実行しても、以下のエラーとなります。
Get-VMComPort : 用語 'Get-VMComPort' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前と して認識されません。名前が正しく記述されていることを確認し、パスが含まれている場合はそのパスが正しいことを確認してから 、再試行してください。 発生場所 行:1 文字:1 + Get-VMComPort + ~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (Get-VMComPort:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException |
(2) PowerShell を管理者権限で起動
(3) 以下を実行して、2 つの COM ポートの存在を確認
Get-VMComPort -VMName <仮想マシン名>
<仮想マシン名>は、Hyper-Vマネージャーの「仮想マシン」の「名前」、もしくは、Get-VM コマンドレットで「Name」に表示される名前です。
例えば、仮想マシン名を Win2012R2VM としたとすると、上記コマンドレットの実行結果は、以下のようになります。
> Get-VMComPort -VMName Win2012R2VM
VMName Name Path ------ ---- ---- Win2012R2VM COM 1 Win2012R2VM COM 2 |
ちなみに、仮想マシン上のデバイスマネージャーでは、COM ポートは表示されません。以下の図のように「非表示のデバイスの表示」を有効にしても、同様です。
(4) 以下を実行して、COM 1 に名前付きパイプを設定
Set-VMComPort -VMName <仮想マシン名> -Path \\.\pipe\<パイプ名> -Number <COMポートのID(1または2)>
例えば、以下のように実行します。
Set-VMComPort -VMName Win2012R2VM -Path \\.\pipe\com1 -Number 1 |
(5) 以下を実行して、COM 1 に名前付きパイプが設定されたことを確認
例えば、実行結果は以下のようになります。
> Get-VMComPort -VMName Win2012R2VM
VMName Name Path ------ ---- ---- Win2012R2VM COM 1 \\.\pipe\com1 Win2012R2VM COM 2 |
(6) セキュアブートの無効化
仮想マシン上のゲスト OS が起動している場合には、ゲスト OS のシャットダウンを行った後、以下の (a), (b) のいずれかを実行して、仮想マシンのセキュアブートを無効化します。
(a) PowerShell コマンドレットから以下を実行
Set-VMFirmware -VMName <仮想マシン名> -EnableSecureBoot Off
(b) Hyper-V マネージャーで、仮想マシンの[設定]の左側のペインから、[ハードウェア]の下の[ファームウェア]を選択し、右側のペインの[セキュア ブートを有効にする]のチェックを外す
ちなみに、上記(a),(b)のいずれかをせずに、次の手順 (7) で msconfig.exe の設定をして[適用]しても、以下のエラーが表示されます。
「システム構成では、後で復元するための元のブート構成を保存できません。ブートの変更は、元の状態に戻されます。この値はセキュアブート ポリシーによって保護されているため、変更または削除できません。」
2. 仮想マシン上のゲスト OS 側の設定
(7) 仮想マシン上のゲスト OS を起動し、その中で、デバッグ オプション、デバッグ ポート、ボー レートの設定を行います。
例えば、msconfig.exe を使用しますので、その手順は、「Hyper-Vなどの仮想OSにwindbgをアタッチする方法」の「1. 仮想 OS 側の設定」の(1)と同じですので、ここでは割愛します。
3. WinDbg 側の設定
(8) windbg.exe を管理者権限で起動し、カーネルデバッグ設定で、ボー レートやポートの設定を行います。
こちらも、具体的な手順は、「Hyper-Vなどの仮想OSにwindbgをアタッチする方法」の「2. Windbg 側の設定」と同じですので、ここでは割愛します。
ご興味のある方は、お試しいただければ幸いです。
[参考文献]
- Hyper-V generation 2 virtual machines - part 5
https://blogs.technet.com/b/jhoward/archive/2013/10/31/hyper-v-generation-2-virtual-machines-part-5.aspx
- Get-VMComPort
https://technet.microsoft.com/en-us/library/hh848587.aspx
- Set-VMComPort
https://technet.microsoft.com/en-us/library/hh848616.aspx
- Set-VMFirmware
https://technet.microsoft.com/en-us/library/dn464287.aspx