所有.NET异常都源于System.Exception以及以下成员变量。
- Data
- HelpLink
- InnerException
- Message
- Source
- StackTrace
- TargetSite
除了这些基本信息之外,System.Exception通常会添加一些成员变量,它们在其中存储特定于该类型异常的信息。这一次我想谈谈一些特殊的例外情况,我们可以深入研究,以获得比乍看起来更多的信息。
更具体地说,我将讨论以下编译或加载异常:
- System.Web.HttpCompileException
- System.Web.HttpParseException
- System.IO.FileNotFoundException
这里的假设是,您已经用adplus收集了一个内存转储,并且在运行!dumpheap -type时发现堆上存在上述异常之一。
System.Web.HttpCompileException
错误消息示例:
CS0246: The type or namespace name ‘<namespace>‘ could not be found (are you missing a using directive or an assembly reference?)
0:005> !PrintException 02d030cc Exception object: 02d030cc Exception type: System.Web.HttpCompileException Message: External component has thrown an exception. InnerException: <none> StackTrace (generated): SP IP Function 0F6FF25C 689B1B01 System.Web.Compilation.AssemblyBuilder.Compile() 0F6FF2A4 686DB64A System.Web.Compilation.WebDirectoryBatchCompiler.CompileAssemblyBuilder(System.Web.Compilation.AssemblyBuilder) 0F6FF2D4 68675054 System.Web.Compilation.WebDirectoryBatchCompiler.CompileNonDependentBuildProviders(System.Collections.ICollection) 0F6FF334 686706A2 System.Web.Compilation.WebDirectoryBatchCompiler.Process() 0F6FF35C 6867027E System.Web.Compilation.BuildManager.BatchCompileWebDirectoryInternal(System.Web.Hosting.VirtualDirectory, Boolean) StackTraceString: <none> HResult: 80004005 The current thread is unmanaged
将此信息与我们在浏览器中获取的相同异常信息进行比较:
Compilation Error
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
Compiler Error Message: CS0246: The type or namespace
name ‘BusinessStuff‘ could not be found (are you missing a using
directive or an assembly reference?)
Source Error:
Line 9: using System.Web.UI.WebControls.WebParts; Line 10: using System.Web.UI.HtmlControls; Line 11: using BusinessStuff; Line 12: Line 13: public partial class Default4 : System.Web.UI.Page
如果我们在堆里有这种类型的信息,清除异常可能会是小菜一碟。那么我们如何从转储中的异常中获取这些信息呢?
如果我们看一下msdn中HttpCompileException的定义,我们会发现除了标准的异常成员变量外,HttpCompileException还有两个额外的成员变量,称为Results和SourceCode。结果将填充实际的编译错误,SourceCode包含未能编译的文件的源代码。
0:005> !do 02d030cc Name: System.Web.HttpCompileException MethodTable: 68a5f4b4 EEClass: 68a5f434 Size: 100(0x64) bytes (C:\WINDOWS\assembly\GAC_32\System.Web\2.0.0.0__b03f5f7f11d50a3a\System.Web.dll) Fields: MT Field Offset Type VT Attr Value Name ... 790fed1c 4000f97 48 System.Int32 0 instance 0 _httpCode 68a5c4d8 4000f98 44 ...eb.ErrorFormatter 0 instance 02d164c8 _errorFormatter 790fed1c 4000f99 4c System.Int32 0 instance 0 _webEventCode 7a754b50 4000f9b 50 ...r.CompilerResults 0 instance 02cd8520 _results 790fa3e0 4000f9c 54 System.String 0 instance 02d0e424 _sourceCode
在_results中,我们可以找到错误号(CS0246)、消息(找不到类型或命名空间名称“BusinessStuff”(是否缺少using指令或程序集引用?),源文件(default4.aspx.c)行号(11)如下:
0:005> !do 02cd8520 Name: System.CodeDom.Compiler.CompilerResults MethodTable: 7a754b50 EEClass: 7a754ae0 Size: 36(0x24) bytes (C:\WINDOWS\assembly\GAC_MSIL\System\2.0.0.0__b77a5c561934e089\System.dll) Fields: MT Field Offset Type VT Attr Value Name 7a754bd4 4000f55 4 ...erErrorCollection 0 instance 02cd8544 errors 7a74847c 4000f56 8 ....StringCollection 0 instance 02cd8568 output ... 0:005> !do 02cd8544 Name: System.CodeDom.Compiler.CompilerErrorCollection MethodTable: 7a754bd4 EEClass: 7a7b07c4 Size: 12(0xc) bytes (C:\WINDOWS\assembly\GAC_MSIL\System\2.0.0.0__b77a5c561934e089\System.dll) Fields: MT Field Offset Type VT Attr Value Name 791036b0 40008f1 4 ...ections.ArrayList 0 instance 02cd8550 list 0:005> !do 02cd8550 Name: System.Collections.ArrayList MethodTable: 791036b0 EEClass: 79103604 Size: 24(0x18) bytes (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll) Fields: MT Field Offset Type VT Attr Value Name 79124228 40008c0 4 System.Object[] 0 instance 02d02b68 _items 790fed1c 40008c1 c System.Int32 0 instance 1 _size ... 0:005> dc 02d02b68 02d02b68 79124228 00000004 790f9c18 02d0281c (B.y.......y.(.. 02d02b78 00000000 00000000 00000000 00000000 ................ ... 0:005> !do 02d0281c Name: System.CodeDom.Compiler.CompilerError MethodTable: 7a7650e4 EEClass: 7a7b79f0 Size: 32(0x20) bytes (C:\WINDOWS\assembly\GAC_MSIL\System\2.0.0.0__b77a5c561934e089\System.dll) Fields: MT Field Offset Type VT Attr Value Name 790fed1c 4000f38 10 System.Int32 0 instance 11 line 790fed1c 4000f39 14 System.Int32 0 instance 7 column 790fa3e0 4000f3a 4 System.String 0 instance 02d02a40 errorNumber 79104f64 4000f3b 18 System.Boolean 0 instance 0 warning 790fa3e0 4000f3c 8 System.String 0 instance 02d02a60 errorText 790fa3e0 4000f3d c System.String 0 instance 02d02980 fileName 0:005> !do 02d02a40 String: CS0246 0:005> !do 02d02a60 String: The type or namespace name ‘BusinessStuff‘ could not be found (are you missing a using directive or an assembly reference?) 0:005> !do 02d02980 String: c:\Inetpub\wwwroot\DebuggerSamples\Default4.aspx.cs
这和源代码一起会给我们提供我们通常在浏览器中看到的所有信息。
System.Web.HttpParseException
或者,包含类型定义的文件可能被外部进程(如病毒扫描程序、索引服务或备份软件)锁定。解决这些问题的最佳方法是查看类型和将在其中定义它的dll,并验证服务器上是否存在该dll。如果是的话,你可以从http://www.sysinternals.com至看看为什么它不能加载dll。
运行!dumpobj(!do)您将看到如下:
0:000> !do 0x184aee84 Name: System.Web.HttpParseException ... 0x79b96824 0x4000020 0x10 CLASS instance 0x184aeed4 _message 0x79b96824 0x4000021 0x14 CLASS instance 0x184aed34 _innerException 0x79b96824 0x4000022 0x18 CLASS instance 0x00000000 _helpURL 0x79b96824 0x4000023 0x1c CLASS instance 0x184aef88 _stackTrace 0x79b96824 0x4000024 0x20 CLASS instance 0x00000000 _stackTraceString 0x79b96824 0x4000025 0x24 CLASS instance 0x00000000 _remoteStackTraceString 0x79b96824 0x4000026 0x2c System.Int32 instance 0 _remoteStackIndex 0x79b96824 0x4000027 0x30 System.Int32 instance -2147467259 _HResult 0x79b96824 0x4000028 0x28 CLASS instance 0x00000000 _source 0x79b96824 0x4000029 0x34 System.Int32 instance 0 _xptrs 0x79b96824 0x400002a 0x38 System.Int32 instance -532459699 _xcode 0x020784fc 0x4000604 0x40 System.Int32 instance 0 _httpCode 0x020784fc 0x4000605 0x3c CLASS instance 0x184aef6c _errorFormatter 0x04392114 0x4000608 0x44 CLASS instance 0x1053b41c _fileName 0x04392114 0x4000609 0x48 System.Int32 instance 1 _line ----------------- Exception 0x184aee84 in MT 0x04392114: System.Web.HttpParseException _message: Parser Error: Could not load type ‘DebuggerSamples.MyPage‘ ...
从这里我们可以查看文件名,看看我们在哪个文件中失败了:
0:000> !do 0x1053b41c String: C:\InetPub\wwwroot\DebuggerSamples\MyPage.aspx
也可以在错误格式化程序中获取源代码
0:000> !do 0x184aef6c Name: System.Web.ParseErrorFormatter ... MT Field Offset Type Attr Value Name 0x052f2fec 0x4000460 0x4 CLASS instance 0x1053b41c _fileName 0x052f2fec 0x4000461 0x8 CLASS instance 0x184ae51c _sourceCode 0x052f2fec 0x4000462 0xc System.Int32 instance 1 _line 0x052f3274 0x4000467 0x10 CLASS instance 0x184aed7c _message 0x052f3274 0x4000468 0x14 CLASS instance 0x184aee84 _excep 0:000> !do 0x184ae51c String: <%@ Page Language="vb" AutoEventWireup="false" Codebehind="MyPage.aspx.vb" Inherits="DebuggerSamples.MyPage"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <title>MyPage</title> <meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1"> <meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1"> <meta name="vs_defaultClientScript" content="JavaScript"> <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5"> </HEAD> <body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> <asp:Button id="MyButton" runat=server /> </form> </body> </HTML>
最后,把它们放在一起,我们可以从ErrorFormatter中看到我们使用Parser错误:Could not load type ‘DebuggerSamples.MyPage‘ on line 1 of C:\InetPub\wwwroot\DebuggerSamples\MyPage.aspx
and line 1 was <%@ Page Language="vb" AutoEventWireup="false" Codebehind="MyPage.aspx.vb" Inherits="DebuggerSamples.MyPage"%>
System.IO.FileNotFoundException
错误消息示例:File or assembly name <assembly name>, or one of its dependencies, was not found
如果进程中加载的某个dll引用了系统上不存在的dll或dll版本,则通常会看到此异常。例如,如果您正在进程中加载使用中函数的控件,则它不一定具有任何递减效果Microsoft.VisualStudio.dll或者stdole.dll用于设计时目的,但不用于运行时目的。
这是一个示例,看看!dumpobj的输出:
0:000> !do 0x1031b1fc Name: System.IO.FileNotFoundException MethodTable 0x79bfbdcc EEClass 0x79bfbe5c Size 72(0x48) bytes GC Generation: 2 mdToken: 0x02000345 (c:\windows\microsoft.net\framework\v1.1.4322\mscorlib.dll) FieldDesc*: 0x79bfbec0 MT Field Offset Type Attr Value Name 0x79b96824 0x400001d 0x4 CLASS instance 0x00000000 _className 0x79b96824 0x400001e 0x8 CLASS instance 0x00000000 _exceptionMethod 0x79b96824 0x400001f 0xc CLASS instance 0x00000000 _exceptionMethodString 0x79b96824 0x4000020 0x10 CLASS instance 0x1031b244 _message 0x79b96824 0x4000021 0x14 CLASS instance 0x00000000 _innerException 0x79b96824 0x4000022 0x18 CLASS instance 0x00000000 _helpURL 0x79b96824 0x4000023 0x1c CLASS instance 0x00000000 _stackTrace 0x79b96824 0x4000024 0x20 CLASS instance 0x00000000 _stackTraceString 0x79b96824 0x4000025 0x24 CLASS instance 0x00000000 _remoteStackTraceString 0x79b96824 0x4000026 0x2c System.Int32 instance 0 _remoteStackIndex 0x79b96824 0x4000027 0x30 System.Int32 instance -2147024894 _HResult 0x79b96824 0x4000028 0x28 CLASS instance 0x00000000 _source 0x79b96824 0x4000029 0x34 System.Int32 instance 0 _xptrs 0x79b96824 0x400002a 0x38 System.Int32 instance -532459699 _xcode 0x79bfbdcc 0x4000f23 0x3c CLASS instance 0x14358078 _fileName 0x79bfbdcc 0x4000f24 0x40 CLASS instance 0x1031a570 _fusionLog ----------------- Exception 0x1031b1fc in MT 0x79bfbdcc: System.IO.FileNotFoundException _message: File or assembly name stdole, or one of its dependencies, was not found.
这个异常的有趣部分是_fusionLog,它告诉我们它在哪里查找dll,以及它正在寻找的特定版本以及找不到它的原因。
0:000> !do 0x1031a570 String: === Pre-bind state information === LOG: DisplayName = stdole, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a (Fully-specified) LOG: Appbase = file:///c:/inetpub/wwwroot/DebuggerSamples LOG: Initial PrivatePath = bin Calling assembly : (Unknown). === LOG: Publisher policy file is not found. LOG: No redirect found in host configuration file (C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\aspnet.config). LOG: Using machine configuration file from C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\config\machine.config. LOG: Post-policy reference: stdole, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a LOG: Attempting download of new URL file:///C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/Temporary ASP.NET Files/DebuggerSamples/e2b59b51/5bf1057f/stdole.DLL. LOG: Attempting download of new URL file:///C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/Temporary ASP.NET Files/DebuggerSamples/e2b59b51/5bf1057f/stdole/stdole.DLL. LOG: Attempting download of new URL file:///c:/inetpub/wwwroot/DebuggerSamples/bin/stdole.DLL. LOG: Attempting download of new URL file:///c:/inetpub/wwwroot/DebuggerSamples/bin/stdole/stdole.DLL. LOG: Attempting download of new URL file:///C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/Temporary ASP.NET Files/DebuggerSamples/e2b59b51/5bf1057f/stdole.EXE. LOG: Attempting download of new URL file:///C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/Temporary ASP.NET Files/DebuggerSamples/e2b59b51/5bf1057f/stdole/stdole.EXE. LOG: Attempting download of new URL file:///c:/inetpub/wwwroot/DebuggerSamples/bin/stdole.EXE. LOG: Attempting download of new URL file:///c:/inetpub/wwwroot/DebuggerSamples/bin/stdole/stdole.EXE.
找不到发布者策略文件通常意味着在任何应用程序“路径”中都找不到请求的dll。