线程.ASP中的中止.NET应用程序导致w3wp.exe崩溃

本文关键字:w3wp exe 崩溃 NET ASP 线程 应用程序 | 更新日期: 2023-09-27 18:10:46

不要在这个问题上设置重复标志 -这不是关于"为什么ThreadAbortException发生",而是关于"为什么w3wp.exe进程在ThreadAbortException后终止"。

假设我们有一个简单的web应用程序,代码示例如下:

protected void Page_Load(object sender, EventArgs e)
{
    Response.Redirect("http://google.com");
}

这实际上意味着类似(参见Response.End()被认为是有害的吗?):

protected void Page_Load(object sender, EventArgs e)
{
    ...response write some data...
    System.Threading.Thread.CurrentThread.Abort();
}

在我的机器(Windows 10 Pro + IIS)上,这段代码导致IIS池进程终止,错误代码为0x0(不执行重定向)。在其他机器上(不是Windows 10),这段代码只生成ThreadAborted异常,但是进程继续工作(redirect执行)。

谁能检查一下这个样品并解释一下是怎么回事?

这里有一些与此问题相关的windows事件日志。

log # 1

发生未处理的异常,进程被终止。

应用ID:/LM/W3SVC/1/ROOT/AS

进程ID: 6700

例外:System.Threading.ThreadAbortException

消息:线程被中止。

加:在System.Web.HttpRuntime.ProcessRequestNotificationPrivate (IIS7WorkerRequestwr, HttpContext context)System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper (IntPtrrootedObjectsPointer, IntPtr native/equestcontext, IntPtr moduleData,Int32标志)System.Web.Hosting.PipelineRuntime.ProcessRequestNotification (IntPtrrootedObjectsPointer, IntPtr native/equestcontext, IntPtr moduleData,Int32旗帜)

log # 2

Faulting application name: w3wp.exe, version: 10.0.10240.16384, time stamp: 0x559f3dad
Faulting module name: KERNELBASE.dll, version: 10.0.10240.16384, time stamp: 0x559f3b2a
Exception code: 0xe0434352
Fault offset: 0x000b3e28
Faulting process id: 0x1a2c
Faulting application start time: 0x01d0e4b1b3ed01cb
Faulting application path: C:'WINDOWS'SysWOW64'inetsrv'w3wp.exe
Faulting module path: C:'WINDOWS'SYSTEM32'KERNELBASE.dll
Report Id: 23b5298d-3b36-49c7-a294-de9c864b703f
Faulting package full name: 
Faulting package-relative application ID: 

线程.ASP中的中止.NET应用程序导致w3wp.exe崩溃

我能够在安装了。net 4.6的Server 2008r2上重现这个问题。

我怀疑这是你们其他人遇到的同样的问题;ThreadAbortExceptions在事件日志中杀死应用程序池(尽管任何未处理的异常都会导致我的情况下的问题;但这可能只是一个全局异常处理程序捕获它并以响应结束。结束或重定向)。转储堆栈跟踪也匹配Ian的答案。

为这个问题打开了MS Connect票证,最近的KB hotfix为我解决了这个问题。

连接文章:https://connect.microsoft.com/VisualStudio/feedback/details/1605438/disabling-ryujit-breaks-asp-net

KB热修复补丁:https://support.microsoft.com/en-us/kb/3098786

到目前为止,我只有一个解决方案:

    static class WebExtensions
    {
        public static void EndSafe(this HttpResponse response)
        {
            response.Flush();
            response.SuppressContent = true;
            HttpContext.Current.ApplicationInstance.CompleteRequest();
        }
        public static void RedirectSafe(this HttpResponse response, string url)
        {
            response.Redirect(url, false);
            HttpContext.Current.ApplicationInstance.CompleteRequest();
        }
    }

然而,这迫使我确保在它之后不会执行任何代码:

...some code
response.RedirectSafe(url);
return; //<-- important
...some more code

注意,在某些情况下(例如递归调用),只有"return"是不够的,在某些情况下,您可能需要避免使用"return"(带有try-finally结构)

我今天在Windows 8.1上重新启动安装Windows更新后,遇到了完全相同的问题。

问题是,由于这个问题,我在注册表中手动禁用了RyuJIT,通过添加useLegacyJit DWORD并将其设置为1(参见方法#3)。但是其中一个更新在同一位置创建了UseRyuJIT键并将其设置为1,这显然使ASP感到困惑。净可怕。

解决方案是将useLegacyJit设置为0并发布iisreset。在那之后,世界上一切都是好的。

当我调试w3wp.exe转储时,WinDbg的!clrstack显示了以下帧。也许这将帮助那些有同样错误的人谷歌搜索解决方案:

000000ef9892be98 00007ffa0e2d1fea [HelperMethodFrame: 000000ef9892be98] 
000000ef9892bf80 00007ff99d776588 System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
000000ef9892df90 00007ff9fc172345 [FaultingExceptionFrame: 000000ef9892df90] 
000000ef9892e490 00007ff99d7796c0 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext)
000000ef9892e520 00007ff99d777377 System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
000000ef9892e700 00007ff99d77655a System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
000000ef9892e740 00007ff99d775c11 DomainNeutralILStubClass.IL_STUB_ReversePInvoke(Int64, Int64, Int64, Int32)
000000ef9892ef58 00007ff9fc100b4e [InlinedCallFrame: 000000ef9892ef58] System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr, System.Web.RequestNotificationStatus ByRef)
000000ef9892ef58 00007ff99d78cc1b [InlinedCallFrame: 000000ef9892ef58] System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr, System.Web.RequestNotificationStatus ByRef)
000000ef9892ef30 00007ff99d78cc1b DomainNeutralILStubClass.IL_STUB_PInvoke
000000ef9892f000 00007ff99d77756c System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
000000ef9892f1e0 00007ff99d77655a System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
000000ef9892f220 00007ff99d775c11 DomainNeutralILStubClass.IL_STUB_ReversePInvoke(Int64, Int64, Int64, Int32)
000000ef9892f418 00007ff9fc100da3 [ContextTransitionFrame: 000000ef9892f418]

我在Win7 SP1上遇到了同样的问题。针对。net 4.5.2编译的Web应用程序,运行在。net 4.6上。我还没有搞乱useLegacyJit或useRyuJIT注册表标志。

原来"启用32位应用程序"被不必要地设置为启用在我的应用程序域。