Прерывистый сбой w3wp.exe с ThreadAbortException после обновления .NET 4.6

В течение последних двух дней мы видели прерывистые сбои рабочего процесса w3wp.exe, обслуживающие основной пул приложений для нашего корпоративного веб-сайта. Иногда аварии изолированы, и IIS может успешно перезапустить рабочий процесс. Но если через 5 минут произойдет более 5 сбоев, IIS Rapid Fail Protection запускает и останавливает пул приложений. Вот пример записи из журнала событий приложения непосредственно перед сбоем:

An unhandled exception occurred and the process was terminated.
Application ID: /LM/W3SVC/2/ROOT
Process ID: 3640
Exception: System.Threading.ThreadAbortException
Message: Thread was being aborted.
StackTrace:    at System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context)
   at System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
   at System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)

Сразу после сбоя из-за исключения ThreadAbortEx происходит более серьезное событие:

Faulting application name: w3wp.exe, version: 8.0.9200.16384, time stamp: 0x5010885f
Faulting module name: KERNELBASE.dll, version: 6.2.9200.17366, time stamp: 0x554d16f6
Exception code: 0xe0434352
Fault offset: 0x00010192
Faulting process id: 0xe38
Faulting application start time: 0x01d100dc662652d6
Faulting application path: C:\Windows\SysWOW64\inetsrv\w3wp.exe
Faulting module path: C:\Windows\SYSTEM32\KERNELBASE.dll
Report Id: db5b0d5b-6cd0-11e5-9418-005056900458
Faulting package full name: 
Faulting package-relative application ID: 

Теперь исключение ThreadAbortException никогда не должно приводить к сбою w3wp.exe, поскольку он бросается каждый раз, когда выполняется стандартный Response.Redirect(). MSDN подтверждает это, и я также подтвердил это с помощью простого теста. Однако, по крайней мере, еще один человек видел аналогичную ошибку в последнее время с аналогичной средой: Thread.Abort в приложении ASP.NET приводит к сбою w3wp.exe. (Но это может быть несвязанная проблема.)

Наша среда:

  • Корпоративный веб-сайт с корзиной покупок и веб-сервисами партнеров; Цели .NET 4.5. (900 000 + строк пользовательского кода, включая DLL бизнес-логики и внутренние библиотеки.)
  • 2 веб-сервера VMWare в балансировочном балансе с использованием Windows NLB
  • IIS 8.0/Windows Server Standard/.NET 4.6.00081
  • Пул приложений, запущенный в 32-битном режиме, потому что мы должны поддерживать несколько классических страниц ASP, вызывающих устаревшую библиотеку VB6.

Фон:

За пару дней до начала сбоев мы обновили до .NET 4.6. У нас есть новая функция RyuJIT (настройка по умолчанию), и мы установили все обновления для решения описанной здесь критической проблемы компилятора: http://blogs.msdn.com/b/dotnet/archive/2015/07/28/ryujit-bug-advisory-in-the-net-framework-4-6.aspx.

Мы также развернули новую версию нашего веб-кода (как это делаем несколько раз в неделю). Разумеется, мы дважды проверяем изменения кода для любых потенциальных уязвимостей при сбое, но ни одно из наших изменений не кажется уязвимым для бесконечных циклов, рекурсивных переполнений стека или большого использования памяти - обычные виновники, когда w3wp.exe падает с необработанным исключением.

Иногда авария затрагивает один веб-сервер в течение нескольких минут после другого, но в других случаях затрагивается только один веб-сервер.

Что я пробовал:

  • Перезагрузили серверы и установили все обновления Windows.
  • Проанализированы журналы IIS, чтобы узнать, поступают ли подозрительные/плохие запросы непосредственно перед сбоями. Я не смог найти ни одного шаблона - все запросы выглядите нормально.
  • Включены мини-минипы аварийного отключения для w3wp.exe(как описано в https://msdn.microsoft.com/en-us/library/bb787181.aspx) и проанализированы с помощью WinDbg. К сожалению, CLR "интересный стек" не показывает ничего полезного, просто пара пустых кадров GC, не связанных с нашим кодом:
> 0:026> !clrstack
> OS Thread Id: 0x1ff0 (26)
> Child SP       IP Call Site
> 2321f96c 771bdf8c [GCFrame: 2321f96c]
> 2321f9a4 771bdf8c [GCFrame: 2321f9a4]

Любые идеи?

Update:

Мы вернули .NET 4.6 и последние обновления Windows на наших веб-серверах. Мы отслеживали это в течение 2 или 3 дней, в зависимости от того, когда сервер был откат, и в каждом случае произошли нулевые последующие сбои, несмотря на то, что они поддерживали один и тот же код приложения. Это довольно убедительно доказывает, что либо .NET 4.6, либо другие обновления Windows вызвали прерывистый сбой, не наш код, поскольку w3wp.exe ранее сбой несколько раз в день.

Теперь мы пытаемся доказать это в Microsoft Support, но это тяжелая битва, потому что проблема была случайной, прерывистой, и мы не смогли достоверно воспроизвести ее. (Они предоставили анализ дампа, но это, кажется, красная селедка.) Мы также в процессе повторного применения обновлений в группах и ожидая несколько дней, чтобы наблюдать за сбоями, чтобы изолировать неисправное обновление. Очевидно, что это утомительный процесс.

Обновление # 2:

Теперь мы повторно применили все предварительные обновления Windows Update, которые были удалены при устранении неполадок, и серверы работают в течение нескольких дней без сбоев. Единственное, что осталось повторить, - это .NET 4.6 и собственные обновления, но мое руководство, по понятным причинам, неохотно устанавливает вещи, которые, вероятно, вызовут сбои в производстве. Поэтому я продолжаю работать с MS для анализа различных дампов аварийных ситуаций, чтобы выявить проблему.

Ответ 1

@Jordan Rieger, эта ошибка должна быть исправлена ​​в .NET 4.6.1 Не могли бы вы подтвердить, исправлена ​​ли проблема в новой структуре? Или, если он все еще сохраняется? Спасибо.

Ответ 2

Вы не указали какой-либо код, но данные свидетельствуют о том, что это проблема с вашим кодом приложения, а не с .NET 4.6 или с ThreadAbortException.

Основные шаги по устранению неполадок здесь: вы сказали, что произошли изменения кода и изменения среды; поэтому выведите один из них.

  • Проверить приложение на виртуальной машине с установленным .NET 4.5. Если вы не ошибаетесь, причиной может быть .NET 4.6.

  • Проверьте старую версию вашего приложения на том же сервере. Если проблем не обнаружено, изменение кода может быть причиной.

  • Проверить приложение на компьютере с установленной версией VS.NET, подключиться к процессу w3wp.exe и отладить его (Инструменты > Прикрепить к процессу). Поймайте ThreadAbortException и проведите через него.

  • Если вы этого еще не сделали, вы должны зарегистрировать событие, которое завершит процесс w3wp.exe, хотя это, очевидно, не будет обрабатывать все исключения. Google это, но этот парень описывает решение, которое я также использую

  • Если вы еще этого не сделали, определите обработчик Application_Error в Global для регистрации исключений. Microsoft демонстрирует это. Создайте параметр System.Web.Configuration, который вы можете включить в свой web.config файл, чтобы включить различные уровни ведения журнала, включая запись в локальный файл и запись в журналы событий Windows, например. Вы также можете установить инструмент обработчика ведения журнала, например Elmah.

  • Создайте простое веб-приложение для barebones и проверите Response.Redirect, чтобы проверить, не сработает ли он w3wp.exe (рабочий процесс) с помощью .NET 4.6. Я сделал это, и этого не произошло, поэтому я подозреваю ваш код. Или возможная странная проблема с сервером/патчем. Эти шаги помогут вам определить ее.

Примечание: Несмотря на то, что это не должно повлиять на процесс приложения, я рекомендую устранить проблемы Response.Redirect(). Мы сделали это недавно в приложении Enterprise, и да, это было изменение широкого охвата, но мы больше не получаем исключения TAE. Исправить это просто: просто вызовите Response.Redirect(false);, а затем убедитесь, что нет кода, который будет запускаться после вызова этой функции (например, вызов return). Это сообщение объясняет