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

时间:2022-10-24 09:48:52

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

大家应该知道 .NET异常 本质上就是一个 Object 对象,也就是说只要你执行了 new XXException() 语句,那么它就会分配到 GC Heap 上。

这也就意味着,如果你有一个进程的dump文件,那你就可以从dump中导出程序最近都抛了什么异常,换句话说只要这些异常没有被 GC 回收,你都可以给它找出来。

实现起来很简单,只要在 windbg 中输入如下命令即可。

  1. 0:015>!dumpheap-typeException
  2. ------------------------------
  3. Heap0
  4. AddressMTSize
  5. 02ea6b0c79330a8072
  6. 02ea75f07930eab476
  7. 06f57aa47930eab476
  8. 06f5829c7930eab476
  9. 06f58a947930eab476
  10. 06f5928c7930eab476
  11. 06f59a847930eab476
  12. 06f5a27c7930eab476
  13. 06f5aa747930eab476
  14. 06f5b26c7930eab476
  15. 06f5ba647930eab476
  16. 06f5c25c7930eab476
  17. 06f5ca547930eab476
  18. 06f5d24c7930eab476
  19. total319objects
  20. ------------------------------
  21. total656objects
  22. Statistics:
  23. MTCountTotalSizeClassName
  24. 79333dc0112System.Text.DecoderExceptionFallback
  25. 79333d7c112System.Text.EncoderExceptionFallback
  26. 793172f8264System.UnhandledExceptionEventHandler
  27. 79330c30172System.ExecutionEngineException
  28. 79330ba0172System.*Exception
  29. 79330b10172System.OutOfMemoryException
  30. 79330a80172System.Exception
  31. 79330cc02144System.Threading.ThreadAbortException
  32. 7930eab464649096System.IO.DirectoryNotFoundException
  33. Total656objects

如果你想看某一个具体异常的详细信息,可以使用命令 !pe 02ea6b0c 。

  1. !pe02ea6b0c
  2. Exceptionobject:02ea6b0c
  3. Exceptiontype:System.Exception
  4. Message:Theemailenteredisnotavalidemailaddress
  5. InnerException:
  6. StackTrace(generated):
  7. SPIPFunction
  8. 024AF2C80FE3125EApp_Code_da2s7oyo!BuggyMail.IsValidEmailAddress(System.String)+0x76
  9. 024AF2E80FE31192App_Code_da2s7oyo!BuggyMail.SendEmail(System.String,System.String)+0x4a
  10. StackTraceString:
  11. HResult:80131500
  12. Therearenestedexceptionsonthisthread.Runwith-nestedfordetails

那现在问题来了,我想看所有异常的详细信息怎么办呢?人肉一个一个的用 !pe 命令去执行,那将会多恶心。。。所以友好的方式就是写脚本去提速,这里我使用 .foreach 命令。

  1. .foreach(ex{!dumpheap-typeException-short}){.echo"********************************";!pe${ex}}

上面我用了一个 -short 参数,目的就是只输出 address 地址方便脚本遍历,然后将迭代项送入 !pe ,输出结果如下:

  1. 0:015>.foreach(ex{!dumpheap-typeException-short}){.echo"********************************";!pe${ex}}
  2. ********************************
  3. Exceptionobject:02ea6b0c
  4. Exceptiontype:System.Exception
  5. Message:Theemailenteredisnotavalidemailaddress
  6. InnerException:
  7. StackTrace(generated):
  8. SPIPFunction
  9. 024AF2C80FE3125EApp_Code_da2s7oyo!BuggyMail.IsValidEmailAddress(System.String)+0x76
  10. 024AF2E80FE31192App_Code_da2s7oyo!BuggyMail.SendEmail(System.String,System.String)+0x4a
  11. StackTraceString:
  12. HResult:80131500
  13. Therearenestedexceptionsonthisthread.Runwith-nestedfordetails
  14. ********************************
  15. Exceptionobject:02ea75f0
  16. Exceptiontype:System.IO.DirectoryNotFoundException
  17. Message:Couldnotfindapartofthepath'c:\idontexist\log.txt'.
  18. InnerException:
  19. StackTrace(generated):
  20. SPIPFunction
  21. 024AF044792741F2mscorlib_ni!System.IO.__Error.WinIOError(Int32,System.String)+0xc2
  22. 024AF0A0792EB22Bmscorlib_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
  23. 024AF198792EA882mscorlib_ni!System.IO.FileStream..ctor(System.String,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare,Int32,System.IO.FileOptions)+0x42
  24. 024AF1C07927783Fmscorlib_ni!System.IO.StreamWriter.CreateFile(System.String,Boolean)+0x3f
  25. 024AF1D4792777DBmscorlib_ni!System.IO.StreamWriter..ctor(System.String,Boolean,System.Text.Encoding,Int32)+0x3b
  26. 024AF1F4797EE19Fmscorlib_ni!System.IO.StreamWriter..ctor(System.String)+0x1f
  27. 024AF2040FE31325App_Code_da2s7oyo!Utility.WriteToLog(System.String,System.String)+0x5d
  28. StackTraceString:
  29. HResult:80070003
  30. Therearenestedexceptionsonthisthread.Runwith-nestedfordetails
  31. ********************************
  32. Exceptionobject:02ea7de8
  33. Exceptiontype:System.IO.DirectoryNotFoundException
  34. Message:Couldnotfindapartofthepath'c:\idontexist\log.txt'.
  35. InnerException:
  36. StackTrace(generated):
  37. SPIPFunction
  38. 024AEF60792741F2mscorlib_ni!System.IO.__Error.WinIOError(Int32,System.String)+0xc2
  39. 024AEFBC792EB22Bmscorlib_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
  40. 024AF0B4792EA882mscorlib_ni!System.IO.FileStream..ctor(System.String,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare,Int32,System.IO.FileOptions)+0x42
  41. 024AF0DC7927783Fmscorlib_ni!System.IO.StreamWriter.CreateFile(System.String,Boolean)+0x3f
  42. 024AF0F0792777DBmscorlib_ni!System.IO.StreamWriter..ctor(System.String,Boolean,System.Text.Encoding,Int32)+0x3b
  43. 024AF110797EE19Fmscorlib_ni!System.IO.StreamWriter..ctor(System.String)+0x1f
  44. 024AF1200FE31325App_Code_da2s7oyo!Utility.WriteToLog(System.String,System.String)+0x5d
  45. StackTraceString:
  46. HResult:80070003
  47. Therearenestedexceptionsonthisthread.Runwith-nestedfordetails

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

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

原文链接:https://mp.weixin.qq.com/s/LhxU7Nr8n9bAx1sXKSlT4g