ASP.NET未处理异常(Unhandled Exception)调试试验

问题介绍

网站运行的时候是否遇到过未处理异常(unhandled exception)造成网站进程退出报503(service unavailable)错误?但是也有时未处理异常仅仅是在页面上显示出错信息,网站进程还在照常运行。

  • 为什么同样发生了异常,结果却截然不同?
  • 这种问题该如何调试?

这片文章通过调试试验来揭开这些问题的答案。


第一种情况

ASP.NET网站运行过程中莫名其妙的退出,在系统事件日志中会有如下记录。

Log Name:      System
Source:        Microsoft-Windows-WAS
Date:          10/6/2012 5:20:03 PM
Event ID:      5011
Task Category: None
Level:         Warning
Keywords:      Classic
User:          N/A
Computer:      system-02
Description:
A process serving application pool 'xxx' suffered a fatal communication error with the Windows Process Activation Service. The process id was '5284'. The data field contains the error number.
应用程序日志中有ASP.NET的错误消息
An unhandled exception occurred and the process was terminated.

Application ID: /LM/W3SVC/2/ROOT

Process ID: 3016

Exception: System.Exception

Message: Exception of type 'System.Exception' was thrown.

StackTrace:    at ASP.backgroundexception_aspx.CrashSite(Object arg)
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack)
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)
如果这种错误很短时间内出现次数过多的话,接下来网站就不能访问了,直接返回这样的页面。(这是因为IIS默认提供出错保护,默认情况下在5分钟内出错5次就会自动停掉程序池)


系统日志中也会有这么一条记录。

Log Name:      System
Source:        Microsoft-Windows-WAS
Date:          10/6/2012 6:50:53 PM
Event ID:      5002
Task Category: None
Level:         Error
Keywords:      Classic
User:          N/A
Computer:      system-02
Description:
Application pool 'xxx' is being automatically disabled due to a series of failures in the process(es) serving that application pool.


第二种情况

网站同样报出异常,服务器返回错误页面。


应用程序日志中记录为一个警告,当时系统日志中并没有相应的错误。w3wp进程也没有退出。

Log Name:      Application
Source:        ASP.NET 2.0.50727.0
Date:          10/6/2012 5:54:53 PM
Event ID:      1309
Task Category: Web Event
Level:         Warning
Keywords:      Classic
User:          N/A
Computer:      system-02
Description:
Event code: 3005 
Event message: An unhandled exception has occurred. 
Event time: 10/6/2012 5:54:53 PM 
Event time (UTC): 10/6/2012 9:54:53 AM 
Event ID: 55545893cefc429d895523e8aadc3e01 
Event sequence: 12 
Event occurrence: 3 
Event detail code: 0 
 
Application information: 
    Application domain: /LM/W3SVC/2/ROOT-1-129939906465074620 
    Trust level: Full 
    Application Virtual Path: / 
    Application Path: C:\inetpub\webdebug\ 
    Machine name: DOFWIN8-02 
 
Process information: 
    Process ID: 3016 
    Process name: w3wp.exe 
    Account name: NT AUTHORITY\LOCAL SERVICE 
 
Exception information: 
    Exception type: Exception 
    Exception message: Exception of type 'System.Exception' was thrown. 
 
Request information: 
    Request URL: http://localhost:8080/ForegroundException.aspx 
    Request path: /ForegroundException.aspx 
    User host address: ::1 
    User:  
    Is authenticated: False 
    Authentication Type:  
    Thread account name: NT AUTHORITY\LOCAL SERVICE 
 
Thread information: 
    Thread ID: 6 
    Thread account name: NT AUTHORITY\LOCAL SERVICE 
    Is impersonating: False 
    Stack trace:    at ASP.foregroundexception_aspx.Page_Load(Object sender, EventArgs e) 
   at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
   at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
   at System.Web.UI.Control.OnLoad(EventArgs e)
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
 

调试试验

首先我们来查看并没有造成进程退出的异常页面。通过windbg连接到w3wp进程,然后捕获所有的CLR first chance exception(命令 sxe clr),然后请求这个网页。马上在windbg中我们被通知有异常发生。

(24.119c): CLR exception - code e0434f4d (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
KERNELBASE!RaiseException+0x68:
000007fe`a84089cc 488b8c24c0000000 mov     rcx,qword ptr [rsp+0C0h] ss:00000071`612edf70=00006cb2cdfa4031
线程调用栈如下
0:019> !dumpstack
OS Thread Id: 0x119c (19)
Child-SP         RetAddr          Call Site
00000071612edeb0 000007fe86d398ef KERNELBASE!RaiseException+0x68
00000071612edf90 000007fe87224340 mscorwks!RaiseTheExceptionInternalOnly+0x2ff
00000071612ee080 000007fe27570972 mscorwks!JIT_Throw+0x130
00000071612ee230 000007fe275d0f39 App_Web_qq7atv_i!ASP.foregroundexception_aspx.Page_Load(System.Object, System.EventArgs)+0x52
00000071612ee270 000007fe7c659f8a System_Web_RegularExpressions!System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)+0x19
00000071612ee2a0 000007fe7c650744 System_Web_ni!System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)+0x2a
00000071612ee2d0 000007fe7c6507a2 System_Web_ni!System.Web.UI.Control.OnLoad(System.EventArgs)+0x84
00000071612ee310 000007fe7c64cd2c System_Web_ni!System.Web.UI.Control.LoadRecursive()+0x42
00000071612ee360 000007fe7c64c230 System_Web_ni!System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)+0x97c
00000071612ee430 000007fe7c64c15b System_Web_ni!System.Web.UI.Page.ProcessRequest(Boolean, Boolean)+0xa0
00000071612ee490 000007fe7c64c0f0 System_Web_ni!System.Web.UI.Page.ProcessRequest()+0x5b
00000071612ee4f0 000007fe275702f4 System_Web_ni!System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)+0xf0
00000071612ee550 000007fe7c653597 App_Web_qq7atv_i!ASP.foregroundexception_aspx.ProcessRequest(System.Web.HttpContext)+0x34
00000071612ee580 000007fe7c61675b System_Web_ni!System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+0x257
00000071612ee630 000007fe7cd04bc1 System_Web_ni!System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)+0xab
00000071612ee6d0 000007fe7ccf54b2 System_Web_ni!System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Exception)+0x511
00000071612ee860 000007fe7ccd6f69 System_Web_ni!System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext, System.AsyncCallback)+0x72
00000071612ee8b0 000007fe7cdfebc1 System_Web_ni!System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext)+0x269
00000071612ee9d0 000007fe7cdfe78b System_Web_ni!System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)+0x411
00000071612eeb50 000007fe7cdfe3c4 System_Web_ni!System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)+0x2b
00000071612eebb0 000007fe86ddb0ca System_Web_ni!DomainNeutralILStubClass.IL_STUB(Int64, Int64, Int64, Int32)+0x24
...
00000071612efad0 000007fe994c11f6 webengine!W3_MGD_HANDLER::ProcessNotification+0x107
00000071612efb20 000007fe86c975f7 webengine!ProcessNotificationCallback+0x46
00000071612efb50 000007fe86ca970a mscorwks!UnManagedPerAppDomainTPCount::DispatchWorkItem+0x157
00000071612efbf0 000007fe86d5f3a4 mscorwks!ThreadpoolMgr::WorkerThreadStart+0x1ba
00000071612efc90 000007feaa62167e mscorwks!Thread::intermediateThreadProc+0x78
00000071612efe60 000007feab35c3f1 KERNEL32!BaseThreadInitThunk+0x1a
00000071612efe90 0000000000000000 ntdll!RtlUserThreadStart+0x1d

我们直接接下来我们将会收到一个错误页面包含了相应的异常信息,可以推断出来很有可能是这个逻辑调用栈中哪里捕获了这个异常,并且将异常信息写成了html网页发回给了客户端。但是怎么验证这个猜想是个难题,一步一步按照这个调用栈看上去很难发现,因为里面逻辑分支过多(这种方法我尝试过并且放弃了) 这里我们看到错误页面上显示了异常的调用栈信息,这告诉我们这个HttpResponse一定访问了异常调用栈信息,如果我们在调用栈信息的地址加一个访问断点,服务器在组织给客户端回复的过程中的调用过程就可以被我们抓到。

首先我们找到这个异常

0:018> !do 000000a80010e090
Name: System.Exception
MethodTable: 000007fe7e0b7ee8
EEClass: 000007fe7dcbe6b0
Size: 136(0x88) bytes
GC Generation: 0
 (C:\Windows\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
Fields:
              MT            Field           Offset                 Type VT             Attr            Value Name
000007fe7e0b7c20  40000b5        8        System.String  0 instance                0 _className
000007fe7e0b5fc8  40000b6       10 ...ection.MethodBase  0 instance                0 _exceptionMethod
000007fe7e0b7c20  40000b7       18        System.String  0 instance                0 _exceptionMethodString
000007fe7e0b7c20  40000b8       20        System.String  0 instance                0 _message
000007fe7e0af240  40000b9       28 ...tions.IDictionary  0 instance                0 _data
000007fe7e0b7ee8  40000ba       30     System.Exception  0 instance                0 _innerException
000007fe7e0b7c20  40000bb       38        System.String  0 instance                0 _helpURL
000007fe7e0b7510  40000bc       40        System.Object  0 instance       a80010e2b0 _stackTrace
000007fe7e0b7c20  40000bd       48        System.String  0 instance                0 _stackTraceString
000007fe7e0b7c20  40000be       50        System.String  0 instance                0 _remoteStackTraceString
000007fe7e0bee90  40000bf       70         System.Int32  1 instance                0 _remoteStackIndex
000007fe7e0b7510  40000c0       58        System.Object  0 instance                0 _dynamicMethods
000007fe7e0bee90  40000c1       74         System.Int32  1 instance      -2146233088 _HResult
000007fe7e0b7c20  40000c2       60        System.String  0 instance                0 _source
000007fe7e0ba628  40000c3       68        System.IntPtr  1 instance                0 _xptrs
000007fe7e0bee90  40000c4       78         System.Int32  1 instance       -532459699 _xcode

加访问断点然后运行,

ba r4 a80010e2b0
果然断下来了,

0:018> g
Breakpoint 1 hit
mscorwks!ArrayBase::GetDataPtr+0x5:
000007fe`86d06da5 0f85c5312700    jne     mscorwks! ?? ::FNODOBFM::`string'+0x6ae0 (000007fe`86f79f70) [br=0]
0:018> !dumpstack
OS Thread Id: 0x860 (18)
*** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v2.0.50727_64\mscorlib\da1374321aba580a5d2ec1c436b7f627\mscorlib.ni.dll
Child-SP         RetAddr          Call Site
000000a859b1da48 000007fe86c50779 mscorwks!ArrayBase::GetDataPtr+0x5
000000a859b1da50 000007fe86c8af58 mscorwks!StackTraceArray::Size+0x15
000000a859b1da80 000007fe872a1423 mscorwks!DebugStackTrace::GetStackFramesFromException+0x6c
000000a859b1db10 000007fe7dfce723 mscorwks!DebugStackTrace::GetStackFramesInternal+0x1c3
000000a859b1e070 000007fe7dfce6bc mscorlib_ni!System.Diagnostics.StackTrace.CaptureStackTrace(Int32, Boolean, System.Threading.Thread, System.Exception)+0x53
000000a859b1e0d0 000007fe7c5dcede mscorlib_ni!System.Diagnostics.StackTrace..ctor(System.Exception, Boolean)+0x2c
000000a859b1e120 000007fe7c5dce5c System_Web_ni!System.Web.Management.WebThreadInformation..ctor(System.Exception)+0x5e
000000a859b1e160 000007fe7c66f5fd System_Web_ni!System.Web.Management.WebRequestErrorEvent.PreProcessEventInit()+0x3c
000000a859b1e1a0 000007fe7c61c72a System_Web_ni!System.Web.Management.WebBaseEvent.RaiseInternal(System.Web.Management.WebBaseEvent, System.Collections.ArrayList, Int32, Int32)+0x31d
000000a859b1e310 000007fe7c66ebe1 System_Web_ni!System.Web.Management.WebBaseEvent.RaiseSystemEventInternal(System.String, System.Object, Int32, Int32, System.Exception, System.String)+0x17a
000000a859b1e3b0 000007fe7c645cff System_Web_ni!System.Web.Management.WebBaseEvent.RaiseRuntimeError(System.Exception, System.Object)+0x101
000000a859b1e430 000007fe7cccd9c6 System_Web_ni!System.Web.HttpResponse.ReportRuntimeError(System.Exception, Boolean, Boolean)+0x6f
000000a859b1e490 000007fe7ccd6c38 System_Web_ni!System.Web.HttpContext.ReportRuntimeErrorIfExists(System.Web.RequestNotificationStatus ByRef)+0x256
000000a859b1e520 000007fe7ccd6fec System_Web_ni!System.Web.HttpRuntime.FinishRequestNotification(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext, System.Web.RequestNotificationStatus ByRef)+0x58
000000a859b1e590 000007fe7cdfebc1 System_Web_ni!System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext)+0x2ec
000000a859b1e6b0 000007fe7cdfe78b System_Web_ni!System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)+0x411
000000a859b1e830 000007fe7cdfe3c4 System_Web_ni!System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)+0x2b
...
000000a859b1f800 000007fe86c975f7 webengine!ProcessNotificationCallback+0x46
000000a859b1f830 000007fe86ca970a mscorwks!UnManagedPerAppDomainTPCount::DispatchWorkItem+0x157
000000a859b1f8d0 000007fe86d5f3a4 mscorwks!ThreadpoolMgr::WorkerThreadStart+0x1ba
000000a859b1f970 000007feaa62167e mscorwks!Thread::intermediateThreadProc+0x78
000000a859b1fb40 000007feab35c3f1 KERNEL32!BaseThreadInitThunk+0x1a
000000a859b1fb70 0000000000000000 ntdll!RtlUserThreadStart+0x1d

根据这个调用栈信息我们就可以看到异常全被catch住加到了context的Error中,最后通过接下来的调用栈组织回复发送给客户端。

private RequestNotificationStatus ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context)
{
	RequestNotificationStatus requestNotificationStatus = RequestNotificationStatus.Pending;
	try
	{
		//处理逻辑省略
	}
	catch (Exception errorInfo)
	{
		requestNotificationStatus = RequestNotificationStatus.FinishRequest;
		context.Response.InitResponseWriter();
		context.AddError(errorInfo);
	}
	if (requestNotificationStatus != RequestNotificationStatus.Pending)
	{
		this.FinishRequestNotification(wr, context, ref requestNotificationStatus);
	}
	return requestNotificationStatus;
}

至此第一个问题我们解决了一半。接下来看第二个造成进程推出的请求。

同样的调试流程,断点first chance exception,发生第一次异常

(3ac.860): CLR exception - code e0434f4d (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
KERNELBASE!RaiseException+0x68:
000007fe`a84089cc 488b8c24c0000000 mov     rcx,qword ptr [rsp+0C0h] ss:000000a8`59b1e4a0=00003fce0bb4ed87
0:018> !pe
Exception object: 000000a80013e0e0
Exception type: System.Exception
Message: <none>
InnerException: <none>
StackTrace (generated):
<none>
StackTraceString: <none>
HResult: 80131500
0:018> !dumpstack
OS Thread Id: 0x860 (18)
Child-SP         RetAddr          Call Site
000000a859b1e3e0 000007fe86d398ef KERNELBASE!RaiseException+0x68
000000a859b1e4c0 000007fe87224340 mscorwks!RaiseTheExceptionInternalOnly+0x2ff
000000a859b1e5b0 000007fe275612dd mscorwks!JIT_Throw+0x130
000000a859b1e760 000007fe7df8dc78 App_Web_qq7atv_i!ASP.backgroundexception_aspx.CrashSite(System.Object)+0x4d
000000a859b1e7a0 000007fe86ddd552 mscorlib_ni!System.Threading.ExecutionContext.runTryCode(System.Object)+0x178
000000a859b1e860 000007fe86d1a283 mscorwks!CallDescrWorker+0x82
000000a859b1e8b0 000007fe871bc7af mscorwks!CallDescrWorkerWithHandler+0xd3
000000a859b1e950 000007fe86d13412 mscorwks!MethodDesc::CallDescr+0x2af
000000a859b1eba0 000007fe8723bcb2 mscorwks!ExecuteCodeWithGuaranteedCleanupHelper+0x12a
000000a859b1ee30 000007fe7df72ba2 mscorwks!ReflectionInvocation::ExecuteCodeWithGuaranteedCleanup+0x172
000000a859b1f040 000007fe7dfe74b1 mscorlib_ni!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)+0x62
000000a859b1f090 000007fe7dfe72ef mscorlib_ni!System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(System.Threading._ThreadPoolWaitCallback)+0x61
000000a859b1f0e0 000007fe86ddd552 mscorlib_ni!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(System.Object)+0x4f
000000a859b1f130 000007fe86d1a283 mscorwks!CallDescrWorker+0x82
000000a859b1f180 000007fe86d1a3ca mscorwks!CallDescrWorkerWithHandler+0xd3
000000a859b1f220 000007fe86d504c7 mscorwks!DispatchCallDebuggerWrapper+0x3e
000000a859b1f280 000007fe86c195cf mscorwks!DispatchCallNoEH+0x5f
000000a859b1f300 000007fe86d5cda4 mscorwks!QueueUserWorkItemManagedCallback+0x83
000000a859b1f390 000007fe86d43721 mscorwks!CClosedHashEx<CCustAttrHashKey,CCustAttrHash>::Hash+0x30
000000a859b1f3e0 000007fe86c3fc59 mscorwks!CNgenEntryBind::Create+0x15d
000000a859b1f4b0 000007fe86d69c4d mscorwks!ThreadExceptionState::GetFlags+0x79
000000a859b1f4f0 000007fe86d5cf31 mscorwks!SharedFileLockHolderBase::DoRelease+0x4d
000000a859b1f520 000007fe86d5cdc9 mscorwks!Thread::DoADCallBack+0x145
000000a859b1f690 000007fe86d43721 mscorwks!CClosedHashEx<CCustAttrHashKey,CCustAttrHash>::Hash+0x55
000000a859b1f6e0 000007fe86c3fc59 mscorwks!CNgenEntryBind::Create+0x15d
000000a859b1f7b0 000007fe86c48993 mscorwks!ThreadExceptionState::GetFlags+0x79
000000a859b1f7f0 000007fe86ca970a mscorwks!ManagedPerAppDomainTPCount::DispatchWorkItem+0x12b
000000a859b1f8d0 000007fe86d5f3a4 mscorwks!ThreadpoolMgr::WorkerThreadStart+0x1ba
000000a859b1f970 000007feaa62167e mscorwks!Thread::intermediateThreadProc+0x78
000000a859b1fb40 000007feab35c3f1 KERNEL32!BaseThreadInitThunk+0x1a
000000a859b1fb70 0000000000000000 ntdll!RtlUserThreadStart+0x1d
这里我们看到这个线程并不是一个处理请求的线程,而是线程池中的一个后台线程调用了我们页面逻辑抛出了异常。那这个异常有相应的处理方法么?接下来继续运行。
(3ac.860): CLR exception - code e0434f4d (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
KERNELBASE!RaiseException+0x68:
000007fe`a84089cc 488b8c24c0000000 mov     rcx,qword ptr [rsp+0C0h] ss:000000a8`59b1f100=00003fce0bb4fe27

0:018> !dumpstack
OS Thread Id: 0x860 (18)
Child-SP         RetAddr          Call Site
000000a859b1f040 000007fe86d398ef KERNELBASE!RaiseException+0x68
000000a859b1f120 000007fe870832e7 mscorwks!RaiseTheExceptionInternalOnly+0x2ff
000000a859b1f210 000007fe870854c6 mscorwks!RaiseTheException+0x57
000000a859b1f240 000007fe87108315 mscorwks!BStrFromString+0x66
000000a859b1f270 000007fe8710832b mscorwks!RealCOMPlusThrow+0x35
000000a859b1f2e0 000007fe87128b56 mscorwks!RealCOMPlusThrow+0xb
000000a859b1f310 000007fe86fce2e8 mscorwks!Thread::RaiseCrossContextException+0x2d6
000000a859b1f520 000007fe86d5cdc9 mscorwks! ?? ::FNODOBFM::`string'+0x5ae58
000000a859b1f690 000007fe86d43721 mscorwks!CClosedHashEx<CCustAttrHashKey,CCustAttrHash>::Hash+0x55
000000a859b1f6e0 000007fe86c3fc59 mscorwks!CNgenEntryBind::Create+0x15d
000000a859b1f7b0 000007fe86c48993 mscorwks!ThreadExceptionState::GetFlags+0x79
000000a859b1f7f0 000007fe86ca970a mscorwks!ManagedPerAppDomainTPCount::DispatchWorkItem+0x12b
000000a859b1f8d0 000007fe86d5f3a4 mscorwks!ThreadpoolMgr::WorkerThreadStart+0x1ba
000000a859b1f970 000007feaa62167e mscorwks!Thread::intermediateThreadProc+0x78
000000a859b1fb40 000007feab35c3f1 KERNEL32!BaseThreadInitThunk+0x1a
000000a859b1fb70 0000000000000000 ntdll!RtlUserThreadStart+0x1d

0:018> g
(3ac.860): CLR exception - code e0434f4d (!!! second chance !!!)
KERNELBASE!RaiseException+0x68:
000007fe`a84089cc 488b8c24c0000000 mov     rcx,qword ptr [rsp+0C0h] ss:000000a8`59b1f100=00003fce0bb4fe27

0:018> !dumpstack
OS Thread Id: 0x860 (18)
Child-SP         RetAddr          Call Site
000000a859b1f040 000007fe86d398ef KERNELBASE!RaiseException+0x68
000000a859b1f120 000007fe870832e7 mscorwks!RaiseTheExceptionInternalOnly+0x2ff
000000a859b1f210 000007fe870854c6 mscorwks!RaiseTheException+0x57
000000a859b1f240 000007fe87108315 mscorwks!BStrFromString+0x66
000000a859b1f270 000007fe8710832b mscorwks!RealCOMPlusThrow+0x35
000000a859b1f2e0 000007fe87128b56 mscorwks!RealCOMPlusThrow+0xb
000000a859b1f310 000007fe86fce2e8 mscorwks!Thread::RaiseCrossContextException+0x2d6
000000a859b1f520 000007fe86d5cdc9 mscorwks! ?? ::FNODOBFM::`string'+0x5ae58
000000a859b1f690 000007fe86d43721 mscorwks!CClosedHashEx<CCustAttrHashKey,CCustAttrHash>::Hash+0x55
000000a859b1f6e0 000007fe86c3fc59 mscorwks!CNgenEntryBind::Create+0x15d
000000a859b1f7b0 000007fe86c48993 mscorwks!ThreadExceptionState::GetFlags+0x79
000000a859b1f7f0 000007fe86ca970a mscorwks!ManagedPerAppDomainTPCount::DispatchWorkItem+0x12b
000000a859b1f8d0 000007fe86d5f3a4 mscorwks!ThreadpoolMgr::WorkerThreadStart+0x1ba
000000a859b1f970 000007feaa62167e mscorwks!Thread::intermediateThreadProc+0x78
000000a859b1fb40 000007feab35c3f1 KERNEL32!BaseThreadInitThunk+0x1a
000000a859b1fb70 0000000000000000 ntdll!RtlUserThreadStart+0x1d
最终证明没有可以handle这个异常的处理方法,Second chance exception发生,意味着进程终止。

也就是说,.NET Framework对于未处理异常(unhandled exception)的方式是让他抛出去,crash就crash。如果第一种情况没有System.Web.HttpRuntime的异常处理逻辑,那么第一个页面也会导致进程退出。实际上,这种机制在.NET Framework 1.1版本的时候处理方式是不一样的,之前的处理方式是将unhandled exception吃掉,但这种方式的风险在于真正的逻辑除了问题的时候无从知晓,反而加大了调试难度。所以在.NET Framework 2.0将这种方式改为直接抛出。

当然这里还有一个回到过去的办法,就是更改如下配置,异常将会不再造成crash。

<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="true" />
</runtime>
</configuration>

解决办法

对于这个问题的调试方法相对来说就简单很多,只要我们知道异常的调用栈信息,这个问题就很明了了,所以我们可以通过以下两种方式抓到这个信息。


第一种,把异常调用栈信息记录在日志里,参考这个链接

http://support.microsoft.com/kb/911816/zh-cn


第二种,抓crash dump,各种工具都可以用,

Adplus - http://support.microsoft.com/kb/286350

Windbg - 异常断点 + .dump /ma c:\dumps\youdumpname.dmp

Debugdiag - http://support.microsoft.com/kb/919789/zh-cn



没有更多推荐了,返回首页