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

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

[[431066]]

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

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

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

  1. 0:015> !dumpheap -type Exception 
  2. ------------------------------ 
  3. Heap 0 
  4. Address       MT     Size 
  5. 02ea6b0c 79330a80       72 
  6. 02ea75f0 7930eab4       76 
  7. … 
  8. 06f57aa4 7930eab4       76 
  9. 06f5829c 7930eab4       76 
  10. 06f58a94 7930eab4       76 
  11. 06f5928c 7930eab4       76 
  12. 06f59a84 7930eab4       76 
  13. 06f5a27c 7930eab4       76 
  14. 06f5aa74 7930eab4       76 
  15. 06f5b26c 7930eab4       76 
  16. 06f5ba64 7930eab4       76 
  17. 06f5c25c 7930eab4       76 
  18. 06f5ca54 7930eab4       76 
  19. 06f5d24c 7930eab4       76 
  20. total 319 objects 
  21. ------------------------------ 
  22. total 656 objects 
  23. Statistics
  24.       MT    Count    TotalSize Class Name 
  25. 79333dc0        1           12 System.Text.DecoderExceptionFallback 
  26. 79333d7c        1           12 System.Text.EncoderExceptionFallback 
  27. 793172f8        2           64 System.UnhandledExceptionEventHandler 
  28. 79330c30        1           72 System.ExecutionEngineException 
  29. 79330ba0        1           72 System.StackOverflowException 
  30. 79330b10        1           72 System.OutOfMemoryException 
  31. 79330a80        1           72 System.Exception 
  32. 79330cc0        2          144 System.Threading.ThreadAbortException 
  33. 7930eab4      646        49096 System.IO.DirectoryNotFoundException 
  34. Total 656 objects 

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

  1. !pe 02ea6b0c 
  2. Exception object: 02ea6b0c 
  3. Exception type: System.Exception 
  4. Message: The email entered is not a valid email address 
  5. InnerException: <none> 
  6. StackTrace (generated): 
  7.     SP       IP       Function 
  8.     024AF2C8 0FE3125E App_Code_da2s7oyo!BuggyMail.IsValidEmailAddress(System.String)+0x76 
  9.     024AF2E8 0FE31192 App_Code_da2s7oyo!BuggyMail.SendEmail(System.String, System.String)+0x4a 
  10.  
  11. StackTraceString: <none> 
  12. HResult: 80131500 
  13. There are nested exceptions on this thread. Run with -nested for details 

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

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

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

  1. 0:015> .foreach (ex {!dumpheap -type Exception -short}){.echo "********************************";!pe ${ex} } 
  2. ******************************** 
  3. Exception object: 02ea6b0c 
  4. Exception type: System.Exception 
  5. Message: The email entered is not a valid email address 
  6. InnerException: <none> 
  7. StackTrace (generated): 
  8.     SP       IP       Function 
  9.     024AF2C8 0FE3125E App_Code_da2s7oyo!BuggyMail.IsValidEmailAddress(System.String)+0x76 
  10.     024AF2E8 0FE31192 App_Code_da2s7oyo!BuggyMail.SendEmail(System.String, System.String)+0x4a 
  11.  
  12. StackTraceString: <none> 
  13. HResult: 80131500 
  14. There are nested exceptions on this thread. Run with -nested for details 
  15. ******************************** 
  16. Exception object: 02ea75f0 
  17. Exception type: System.IO.DirectoryNotFoundException 
  18. Message: Could not find a part of the path 'c:\idontexist\log.txt'
  19. InnerException: <none> 
  20. StackTrace (generated): 
  21.     SP       IP       Function 
  22.     024AF044 792741F2 mscorlib_ni!System.IO.__Error.WinIOError(Int32, System.String)+0xc2 
  23.     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 
  24.     024AF198 792EA882 mscorlib_ni!System.IO.FileStream..ctor(System.String, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare, Int32, System.IO.FileOptions)+0x42 
  25.     024AF1C0 7927783F mscorlib_ni!System.IO.StreamWriter.CreateFile(System.String, Boolean)+0x3f 
  26.     024AF1D4 792777DB mscorlib_ni!System.IO.StreamWriter..ctor(System.String, Boolean, System.Text.Encoding, Int32)+0x3b 
  27.     024AF1F4 797EE19F mscorlib_ni!System.IO.StreamWriter..ctor(System.String)+0x1f 
  28.     024AF204 0FE31325 App_Code_da2s7oyo!Utility.WriteToLog(System.String, System.String)+0x5d 
  29.  
  30. StackTraceString: <none> 
  31. HResult: 80070003 
  32. There are nested exceptions on this thread. Run with -nested for details 
  33. ******************************** 
  34. Exception object: 02ea7de8 
  35. Exception type: System.IO.DirectoryNotFoundException 
  36. Message: Could not find a part of the path 'c:\idontexist\log.txt'
  37. InnerException: <none> 
  38. StackTrace (generated): 
  39.     SP       IP       Function 
  40.     024AEF60 792741F2 mscorlib_ni!System.IO.__Error.WinIOError(Int32, System.String)+0xc2 
  41.     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 
  42.     024AF0B4 792EA882 mscorlib_ni!System.IO.FileStream..ctor(System.String, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare, Int32, System.IO.FileOptions)+0x42 
  43.     024AF0DC 7927783F mscorlib_ni!System.IO.StreamWriter.CreateFile(System.String, Boolean)+0x3f 
  44.     024AF0F0 792777DB mscorlib_ni!System.IO.StreamWriter..ctor(System.String, Boolean, System.Text.Encoding, Int32)+0x3b 
  45.     024AF110 797EE19F mscorlib_ni!System.IO.StreamWriter..ctor(System.String)+0x1f 
  46.     024AF120 0FE31325 App_Code_da2s7oyo!Utility.WriteToLog(System.String, System.String)+0x5d 
  47.  
  48. StackTraceString: <none> 
  49. HResult: 80070003 
  50. There are nested exceptions on this thread. Run with -nested for details 

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

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

 

责任编辑:武晓燕 来源: 一线码农聊技术
相关推荐

2015-11-06 10:40:27

2021-03-15 10:01:20

CDNIP黑客

2023-06-10 00:11:52

GPT-4DeepMindAlphaGo

2019-12-16 10:43:38

Linux内存消耗进程

2019-12-16 09:10:38

Linux中央处理器进程

2019-11-06 15:58:54

Linux内存消耗进程

2019-12-16 11:00:04

LinuxCPU进程

2016-12-08 12:47:05

Linux在线主机IP地址

2022-09-28 08:58:36

Linux进程

2017-12-18 10:12:48

LinuxShell命令

2012-12-13 13:46:08

2022-09-29 09:17:47

进程Linux创建

2009-04-02 15:21:43

c#IDisposeFinalize

2011-01-26 13:26:32

Linux进程

2009-11-22 12:20:05

2023-07-07 13:56:54

2009-01-05 09:14:17

.NETcatch性能损失

2009-06-17 09:06:59

Unix系统资源进程

2018-02-24 17:50:43

Linux进程ID命令

2013-08-19 17:25:18

.Net托管
点赞
收藏

51CTO技术栈公众号