今回の話題は、WinDbgの操作をオートメーションするスクリプト、PowerDbgの使い方です。これはなにかというと、WinDbgのコンソール版、cdb.exeのフロントエンドです。PowerShellがデバッガになるというよりは、windbgをコントロールできる感じです。
インストール方法
http://powerdbg.codeplex.com/ に行き、Downloadボタンを押すと、zipが落ちてくるので開きます。その中に「Install_PowerDbg.bat」というファイルがあるので、実行するとインストールされます。といっても、横に置いてある「PowerDbg.psm1」を「%USERPROFILE%\Documents\WindowsPowerShell\Modules\PowerDbg」にコピーするだけなので、手でやっても変わらないです(もっと言うと、好きな場所に置いて毎回Import-Module .\PowerDbg.psm1でもいいです)。
あとは、いくつかの方法のどれかでcdb.exeのあるフォルダを指定します。でも一番簡単なのは.psm1の頭、param(...)のあとに以下のように記述することなので、ここではそれだけ書きます(どうせスクリプトは更新されなさそうだし)。
$debuggerRoot = "C:\Program Files (x86)\Windows Kits\8.0\Debuggers\x64"
使い方
「New-DbgSession」コマンドレットで、デバッガを起動できます。-command "コマンド..."で新コマンド起動、-process "プロセス名" でアタッチ、-dump "dumpファイルのパス" でダンプ読み込みです。PS> New-DbgSession -command "C:\Program Files (x86)\MsbuildLauncher\MsbuildLauncher.exe"
そして、「Invoke-DbgCommand」でデバッガコマンドを送れます。
PS> Invoke-DbgCommand 'bp $exentry'
「g」は「Send-DbgGo」というコマンドレットが用意されているので使えます。
PS> Send-DbgGoSend-DbgGoすると、止まるまでブロックします。Ctrl+Cで抜けることも可能。
終わりたいときは、「Exit-DbgSession」で終われます。
PS> Exit-DbgSession
.loadby sos clrみたいに拡張をロードしたいときは、Load-DbgExtensionが使えます。
PS> Load-DbgExtension sos clr
Invoke-DbgCommandで何を送るかが肝で、PowerShell固有の操作はほとんどありません。(引数名がcamelCaseなのがいけてない感じですがスルーでおねがいします…)
実用例1: 異常終了したときに.NETのスタックトレース等を表示するスクリプト
前にやった「WinDbgとSOS拡張でVSを使わずに.NETアプリをデバッグ - 異常終了時の調査」を自動でやれます。実行するとこんな感じ。
PS> > .\PrintExceptionSecondChance.ps1 -Command "C:\temp\MsbuildLauncher-0.1.1\MsbuildLauncher\MsbuildLauncher.exe" ModLoad: 000007fe`f7200000 000007fe`f7b60000 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll ntdll!ZwMapViewOfSection+0xa: 00000000`7755153a c3 ret (1340.8e8): Unknown exception - code 04242420 (first chance) ModLoad: 000007fe`f5a60000 000007fe`f5b8e000 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clrjit.dll ntdll!ZwMapViewOfSection+0xa: 00000000`7755153a c3 ret (1340.8e8): C++ EH exception - code e06d7363 (first chance) (1340.8e8): C++ EH exception - code e06d7363 (first chance) (1340.8e8): C++ EH exception - code e06d7363 (first chance) (1340.8e8): C++ EH exception - code e06d7363 (first chance) (1340.8e8): C++ EH exception - code e06d7363 (first chance) (1340.8e8): CLR exception - code e0434352 (first chance) ←ここでエディタパスをおかしくして「Edit」ボタンをクリック (1340.16c0): Unknown exception - code 000006ba (first chance) (1340.8e8): CLR exception - code e0434352 (first chance) (1340.8e8): CLR exception - code e0434352 (!!! second chance !!!) *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\system32\KERNELBASE.dll - *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\Microsoft.NET\Framework64\v4.0.3 0319\clr.dll - KERNELBASE!RaiseException+0x3d: 000007fe`fd6a940d 4881c4c8000000 add rsp,0C8h PDB symbol for clr.dll not loaded Exception object: 0000000002b0eeb8 Exception type: System.ComponentModel.Win32Exception Message: 指定されたファイルが見つかりません。 InnerException:StackTrace (generated): (略)
実用例2: .NETなプログラムのプロセスのダンプファイルを読み取ってスタックトレースを出力するスクリプト
実はいつもやってる「clr.dllが読み込まれるまで進める」という処理が必要なければ、New-DbgSessionは-sosというオプションでsos.dllを自動で読んでくれるのです。それを利用すると、これだけ簡潔にできます。どうでしょうか?今回の例はとくにPowerShellらしさはないですが、特定のブレイクポイントを一気に仕掛けるとか、結果に応じてどうこうするなんて用途には便利かと思います。
0 件のコメント:
コメントを投稿