troushoo

[SOS]!PrintException:例外情報の表示

WinDbg等で使用できる.NET用のデバッガエクステンションsosで例外情報を表示する!PrintExceptionについて説明します。

今回使用するアプリ
以下のアプリで例外発生時のダンプを調査します。

class MyClass
{
    public int a = 0x0;
}
 
class Program
{
    static void Main(string[] args)
    {
        MyClass mc = new MyClass();
        func(mc.a);
    }
    static void func(int a)
    {
        Console.WriteLine(5 / a);
    }
}

[!PrintException]
!PrintExceptionは現在のスレッドの最後に発生した例外の詳細情報を表示します。

以下使用例です。
まず、上記のアプリのダンプを取得し、WinDbgで開きます。
sos.dllを読み込んだ後、どのスレッドで例外が発生しているかを!threadsを利用して調べます。

上記よりスレッド0で発生していることがわかります。

0:000> .loadby sos clr
0:000> !threads
ThreadCount: 2
UnstartedThread: 0
BackgroundThread: 1
PendingThread: 0
DeadThread: 0
Hosted Runtime: no
Lock
ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain Count Apt Exception
0 1 d70 00b882e0 2a020 Preemptive 02B2FA8C:00000000 00b81cf0 0 MTA System.DivideByZeroException 02b12488
2 2 fc0 00b94cc8 2b220 Preemptive 00000000:00000000 00b81cf0 0 MTA (Finalizer)


ここでカレントスレッドを0に移動して!PrintExceptionを実行します。

0:000> ~0s
eax=00000000 ebx=00a8eb3c ecx=00000000 edx=00000000 esi=00a8eaac edi=00000000
eip=76ffb554 esp=00a8e984 ebp=00a8eb04 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
ntdll!ZwWaitForMultipleObjects+0xc:
76ffb554 c21400 ret 14h
0:000> !PrintException
Exception object: 02b12488
Exception type: System.DivideByZeroException
Message: Attempted to divide by zero.
InnerException: <none>
StackTrace (generated):
SP IP Function
00A8F0D4 0106010C PrintException!PrintException.Program.func(Int32)+0x1c
00A8F0E0 0106009A PrintException!PrintException.Program.Main(System.String[])+0x4a



StackTraceString: <none>
HResult: 80020012

これにより例外情報が取得でき、例外オブジェクト、メッセージ、スタックトレース等がわかります。
プライベートシンボルがあれば、この状態で!ClrStackを利用すると、ソースコードの何行目で落ちているかもわかります。

0:000> !ClrStack 
OS Thread Id: 0xd70 (0)
Child SP IP Call Site
00a8f238 76ffb554 [GCFrame: 00a8f238]
00a8f0d4 0106010c PrintException.Program.func(Int32) [c:\users\eight\documents\visual studio 2010\Projects\PrintException\PrintException\Program.cs @ 24]
00a8f0e0 0106009a PrintException.Program.Main(System.String[]) [c:\users\eight\documents\visual studio 2010\Projects\PrintException\PrintException\Program.cs @ 19]
00a8f238 72a23570 [GCFrame: 00a8f238]

(補足)
・!PrintExceptionは引数に例外オブジェクトのアドレスを指定することもできます。

0:000> !PrintException 02b12488
Exception object: 02b12488
Exception type: System.DivideByZeroException
Message: Attempted to divide by zero.
InnerException: <none>
StackTrace (generated):
SP IP Function
00A8F0D4 0106010C PrintException!PrintException.Program.func(Int32)+0x1c
00A8F0E0 0106009A PrintException!PrintException.Program.Main(System.String[])+0x4a

StackTraceString: <none>
HResult: 80020012

・!PrintExceptionコマンドは!peと省略することもできます。

リンク
sos.dllのコマンド説明 [MSDN]


  1. 2011/10/26(水) 16:17:00|
  2. SOS・Psscor2/Psscor4
  3. | トラックバック:0
  4. | コメント:0
<<GFlagsでプロセスを殺した犯人捜し | ホーム | Visual Studioでドライバ開発>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://troushoo.blog.fc2.com/tb.php/9-db149e2b
この記事にトラックバックする(FC2ブログユーザー)

スポンサーリンク

最新記事

月別アーカイブ

カテゴリ

ツール (92)
ネットワーク (76)
Visual Studio (56)
SOS・Psscor2/Psscor4 (25)
WinDbg (25)
Linux (24)
Azure (17)
Tips (20)
英語 (1)
About Me (1)
未分類 (0)

全記事表示リンク

全ての記事を表示する

検索フォーム

RSSリンクの表示

リンク

このブログをリンクに追加する