そこで、その、CLR exception(0xe0434352)をWinDbgで追跡する方法をまとめました。
ーーー
まずは、WinDbgを起動します。ターゲットのexeに合っている方(x86,x64)を選んでください。
ーーー
[File]→[Open Executable...]で、exeを開きます。
ーーー
[Debug]→[Event Filters...]を開きます。
"CLR exception"を選び、"Enabled"を選択。閉じます。
ーーー
[Debug]→[Go]で実行します。
ーーー
デバッガが停止した場合、例外コードを確認します。ちょうど、オレンジ色の部分です。
(1c14.1fc4): CLR exception - code e0434352 (first chance)
この例外であれば、次に進みます。
ーーー
SOS.dllを読み込みます。
SOS.dll (SOS デバッガー拡張)
.loadby sos clr
で良いようです。。。
参考:WinDbgとSOS拡張でVSを使わずに.NETアプリをデバッグ - 異常終了時の調査
SOS.dllを読み込むには、通常、次の4つのうち、1つを実行するのですが。。。
.load C:\Windows\Microsoft.NET\Framework\v2.0.50727\SOS.dll
.load C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll
.load C:\Windows\Microsoft.NET\Framework64\v2.0.50727\SOS.dll
.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.dll
WinDbgの出力を見て考えます。画面上に、
C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
という出力が有るので、上から2番目の物が該当します。
.load C:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll
.load がうまくいっても、特にこれといった表示は有りません。
.chain を使うと分かるようです。(.chain は Meta-Commands の 1 つ)
0:000> .chain Extension DLL search Path: C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\WINXP;... Extension DLL chain: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll: image 4.8.4510.0, API 1.0.0, built Fri Apr 1 06:30:03 2022 [path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll] ELFBinComposition: image 10.0.22621.1, API 0.0.0, [path: C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\winext\ELFBinComposition.dll] dbghelp: image 10.0.22621.1, API 10.0.6, [path: C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\dbghelp.dll] exts: image 10.0.22621.1, API 1.0.0, [path: C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\WINXP\exts.dll] uext: image 10.0.22621.1, API 1.0.0, [path: C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\winext\uext.dll] ntsdexts: image 10.0.22621.1, API 1.0.0, [path: C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\WINXP\ntsdexts.dll]
ーーー
次に、3つコマンドを実行しました。その結果が次の図になります。 企業秘密は、黒棒で消しました。
!Threads で、実行中のスレッドの様子を見ています。
!pe (!PrintException) で、例外の中身を確認しています。
!CLRStack で、スタックトレースを確認しています。
ここまでやると、大体は見当が付いてくると思います。
今回の事例では「IContextMenu.GetCommandStringの中で、HRESULTを返す為に『throwを呼ぶ』という手段を選択したことが良くなかった」事が判りました。
0 件のコメント:
コメントを投稿