如何把 .NET 进程中的所有托管异常找出来?

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何把 .NET 进程中的所有托管异常找出来?相关的知识,希望对你有一定的参考价值。

大家应该知道 .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: <none>
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: <none>
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: <none>
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: <none>
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: <none>
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: <none>
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: <none>
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: <none>
HResult: 80070003
There are nested exceptions on this thread. Run with -nested for details

当然你也可以打印出当前异常的内部异常,配上一个 -nest 参数即可。

.foreach (ex {!dumpheap -type Exception -short}){.echo "********************************";!pe –nested ${ex} }

以上是关于如何把 .NET 进程中的所有托管异常找出来?的主要内容,如果未能解决你的问题,请参考以下文章

从非托管进程中卸载 .NET DLL

非托管代码中的 ASP Net Core 1.1 和 EF 6 异常?

HTTP 错误 500.0 - Dot net core 3.1 中的 ASP.NET Core IIS 托管失败(进程中)

asp.net中如何把sql中的数据查找出来,并且倒入到Excel文件中

C# 堆和栈

如何在.Net中列出堆中的所有托管对象?