共计 4693 个字符,预计需要花费 12 分钟才能阅读完成。
导读 | 大家应该知道 .NET 异常 本质上就是一个 Object 对象,也就是说只要你执行了 new XXException() 语句,那么它就会分配到 GC Heap 上。 |
这也就意味着,如果你有一个进程的 dump 文件,那你就可以从 dump 中导出程序最近都抛了什么异常,换句话说只要这些异常没有被 GC 回收,你都可以给它找出来。
实现起来很简单,只要在 windbg 中输入如下命令即可。
0:015> !dumpheap -type Exception | |
------------------------------ | |
Heap 0 | |
Address MT Size | |
02ea6b0c 79330a80 72 | |
02ea75f0 7930eab4 76 | |
… | |
06f57aa4 7930eab4 76 | |
06f5829c 7930eab4 76 | |
06f58a94 7930eab4 76 | |
06f5928c 7930eab4 76 | |
06f59a84 7930eab4 76 | |
06f5a27c 7930eab4 76 | |
06f5aa74 7930eab4 76 | |
06f5b26c 7930eab4 76 | |
06f5ba64 7930eab4 76 | |
06f5c25c 7930eab4 76 | |
06f5ca54 7930eab4 76 | |
06f5d24c 7930eab4 76 | |
total 319 objects | |
------------------------------ | |
total 656 objects | |
Statistics: | |
MT Count TotalSize Class Name | |
79333dc0 1 12 System.Text.DecoderExceptionFallback | |
79333d7c 1 12 System.Text.EncoderExceptionFallback | |
793172f8 2 64 System.UnhandledExceptionEventHandler | |
79330c30 1 72 System.ExecutionEngineException | |
79330ba0 1 72 System.StackOverflowException | |
79330b10 1 72 System.OutOfMemoryException | |
79330a80 1 72 System.Exception | |
79330cc0 2 144 System.Threading.ThreadAbortException | |
7930eab4 646 49096 System.IO.DirectoryNotFoundException | |
Total 656 objects |
如果你想看某一个具体异常的详细信息,可以使用命令 !pe 02ea6b0c。
!pe 02ea6b0c | |
Exception object: 02ea6b0c | |
Exception type: System.Exception | |
Message: The email entered is not a valid email address | |
InnerException: | |
StackTrace (generated): | |
SP IP Function | |
024AF2C8 0FE3125E App_Code_da2s7oyo!BuggyMail.IsValidEmailAddress(System.String)+0x76 | |
024AF2E8 0FE31192 App_Code_da2s7oyo!BuggyMail.SendEmail(System.String, System.String)+0x4a | |
StackTraceString: | |
HResult: 80131500 | |
There are nested exceptions on this thread. Run with -nested for details |
那现在问题来了,我想看所有异常的详细信息怎么办呢? 人肉一个一个的用 !pe 命令去执行,那将会多恶心。。。所以友好的方式就是写脚本去提速,这里我使用 .foreach 命令。
.foreach (ex {!dumpheap -type Exception -short}){.echo "********************************";!pe ${ex} }
上面我用了一个 -short 参数,目的就是只输出 address 地址方便脚本遍历,然后将迭代项送入 !pe,输出结果如下:
0:015> .foreach (ex {!dumpheap -type Exception -short}){.echo "********************************";!pe ${ex} } | |
******************************** | |
Exception object: 02ea6b0c | |
Exception type: System.Exception | |
Message: The email entered is not a valid email address | |
InnerException: | |
StackTrace (generated): | |
SP IP Function | |
024AF2C8 0FE3125E App_Code_da2s7oyo!BuggyMail.IsValidEmailAddress(System.String)+0x76 | |
024AF2E8 0FE31192 App_Code_da2s7oyo!BuggyMail.SendEmail(System.String, System.String)+0x4a | |
StackTraceString: | |
HResult: 80131500 | |
There are nested exceptions on this thread. Run with -nested for details | |
******************************** | |
Exception object: 02ea75f0 | |
Exception type: System.IO.DirectoryNotFoundException | |
Message: Could not find a part of the path 'c:\idontexist\log.txt'. | |
InnerException: | |
StackTrace (generated): | |
SP IP Function | |
024AF044 792741F2 mscorlib_ni!System.IO.__Error.WinIOError(Int32, System.String)+0xc2 | |
024AF0A0 792EB22B mscorlib_ni!System.IO.FileStream.Init(System.String, System.IO.FileMode, System.IO.FileAccess, Int32, Boolean, System.IO.FileShare, Int32, System.IO.FileOptions, SECURITY_ATTRIBUTES, System.String, Boolean)+0x48b | |
024AF198 792EA882 mscorlib_ni!System.IO.FileStream..ctor(System.String, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare, Int32, System.IO.FileOptions)+0x42 | |
024AF1C0 7927783F mscorlib_ni!System.IO.StreamWriter.CreateFile(System.String, Boolean)+0x3f | |
024AF1D4 792777DB mscorlib_ni!System.IO.StreamWriter..ctor(System.String, Boolean, System.Text.Encoding, Int32)+0x3b | |
024AF1F4 797EE19F mscorlib_ni!System.IO.StreamWriter..ctor(System.String)+0x1f | |
024AF204 0FE31325 App_Code_da2s7oyo!Utility.WriteToLog(System.String, System.String)+0x5d | |
StackTraceString: | |
HResult: 80070003 | |
There are nested exceptions on this thread. Run with -nested for details | |
******************************** | |
Exception object: 02ea7de8 | |
Exception type: System.IO.DirectoryNotFoundException | |
Message: Could not find a part of the path 'c:\idontexist\log.txt'. | |
InnerException: | |
StackTrace (generated): | |
SP IP Function | |
024AEF60 792741F2 mscorlib_ni!System.IO.__Error.WinIOError(Int32, System.String)+0xc2 | |
024AEFBC 792EB22B mscorlib_ni!System.IO.FileStream.Init(System.String, System.IO.FileMode, System.IO.FileAccess, Int32, Boolean, System.IO.FileShare, Int32, System.IO.FileOptions, SECURITY_ATTRIBUTES, System.String, Boolean)+0x48b | |
024AF0B4 792EA882 mscorlib_ni!System.IO.FileStream..ctor(System.String, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare, Int32, System.IO.FileOptions)+0x42 | |
024AF0DC 7927783F mscorlib_ni!System.IO.StreamWriter.CreateFile(System.String, Boolean)+0x3f | |
024AF0F0 792777DB mscorlib_ni!System.IO.StreamWriter..ctor(System.String, Boolean, System.Text.Encoding, Int32)+0x3b | |
024AF110 797EE19F mscorlib_ni!System.IO.StreamWriter..ctor(System.String)+0x1f | |
024AF120 0FE31325 App_Code_da2s7oyo!Utility.WriteToLog(System.String, System.String)+0x5d | |
StackTraceString: | |
HResult: 80070003 | |
There are nested exceptions on this thread. Run with -nested for details |
当然你也可以打印出当前异常的内部异常,配上一个 -nest 参数即可。
.foreach (ex {!dumpheap -type Exception -short}){.echo "********************************";!pe –nest
正文完
星哥玩云-微信公众号
