.NET 4.6 升級後 w3wp.exe 間歇性崩潰並出現 ThreadAbortException
在過去的幾天裡,我們看到為我們公司網站的主應用程序池提供服務的 w3wp.exe 工作程序間歇性崩潰。有時崩潰是孤立的,IIS 能夠成功地重新啟動工作程序。但如果 5 分鐘內發生超過 5 次崩潰,IIS 快速故障保護就會啟動並停止應用程序池。以下是崩潰前應用程序事件日誌中的範例條目:
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)由於 ThreadAbortException 導致崩潰後,立即記錄了一個更嚴重的事件:
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 證實了這一點,我也用一個簡單的測試證實了這一點。但是,最近至少有其他人在類似的環境中看到了類似的崩潰:ASP.NET 應用程序中的 Thread.Abort 導致 w3wp.exe 崩潰。(但這可能是一個不相關的問題。)
我們的環境:
- 帶有購物車和合作夥伴網路服務的企業網站;針對 .NET 4.5。(900,000 多行自定義程式碼,包括業務邏輯 DLL 和內部庫。)
- 使用 Windows NLB 的負載平衡池中的 2 個 VMWare Web 伺服器
- IIS 8.0/Windows 2012 伺服器標準/.NET 4.6.00081
- 應用程序池以 32 位模式執行,因為我們必須支持少數呼叫舊版 VB6 DLL 的經典 ASP 頁面。
背景:
在崩潰開始前幾天,我們升級到了 .NET 4.6。我們啟用了新的 RyuJIT(預設設置),並且我們安裝了所有更新以解決此處描述的關鍵編譯器問題:http: //blogs.msdn.com/b/dotnet/archive/2015/07/28/ryujit- bug-advisory-in-the-net-framework-4-6.aspx。
我們還部署了新版本的 Web 程式碼(就像我們每週做幾次一樣)。自然地,我們仔細檢查了程式碼更改是否存在任何潛在的崩潰漏洞,但我們的任何更改似乎都不會受到無限循環、遞歸堆棧溢出或高記憶體使用的影響——當 w3wp.exe 因未處理的異常而崩潰時,這些都是正常的罪魁禍首。
有時崩潰會在幾分鐘內影響另一台 Web 伺服器,但有時只有一台 Web 伺服器受到影響。
我嘗試過的事情:
- 重新啟動伺服器並安裝所有 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]有任何想法嗎?
更新:
我們已在我們的 Web 伺服器上回滾 .NET 4.6 和最近的 Windows 更新。我們已經監視了 2 或 3 天,具體取決於伺服器回滾的時間,並且在每種情況下,儘管維護相同的應用程式碼,但隨後的崩潰都為零。這非常明確地證明 .NET 4.6 或其他 Windows 更新導致間歇性崩潰,而不是我們的程式碼,因為 w3wp.exe 之前每天崩潰幾次。
我們現在正試圖向 Microsoft 支持部門證明這一點,但這是一場艱苦的戰鬥,因為問題是隨機的、間歇性的,而且我們無法可靠地重現它。(他們提供了轉儲分析,但它似乎是在轉移注意力。)我們還在分組重新應用更新並等待幾天以觀察崩潰,以努力隔離錯誤的更新。顯然這是一個乏味的過程。
更新#2:
我們現在重新應用了在故障排除中刪除的所有 pre-.NET 4.6 Windows 更新,並且伺服器已經執行了幾天而沒有崩潰。唯一需要重新應用的是 .NET 4.6 和它自己的更新,但我的管理層不願意安裝可能會導致生產崩潰的東西,這是可以理解的。因此,我將繼續與 MS 合作分析不同的故障轉儲以查明問題。
@Jordan Rieger,這個錯誤應該在 .NET 4.6.1 中修復,您能否確認問題是否在新框架中修復?或者如果它仍然存在?謝謝。
您沒有顯示任何程式碼,但有證據表明這是您的應用程式碼的問題,而不是 .NET 4.6 或
ThreadAbortException特定的問題。這裡的基本故障排除步驟:您說有程式碼更改和環境更改;所以排除其中之一。
- 在安裝了 .NET 4.5 的 VM 上測試應用程序。如果您沒有收到錯誤,可能是 .NET 4.6 的原因。
- 在同一台伺服器上測試您的應用程序的舊版本。如果沒有發現問題,可能是程式碼更改的原因。
- 在安裝了 VS.NET 的機器上測試應用程序,附加到
w3wp.exe程序並調試它(工具 > 附加到程序)。抓住ThreadAbortException並追踪它。- 如果你還沒有,你應該記錄你的
w3wp.exe程序停止的事件。雖然這顯然不會處理所有異常。Google這個,但是這個人描述了一個我也使用的解決方案- 如果您還沒有,請定義一個
Application_Error處理程序Global來記錄異常。微軟展示了這一點。例如,創建一個System.Web.Configuration選項,您可以在web.config文件中切換以啟用不同級別的日誌記錄,包括寫入本地文件和寫入 Windows 事件日誌。您還可以安裝像Elmah這樣的日誌處理程序工具。- 創建一個準系統簡單的 Web 應用程序並測試
Response.Redirect以驗證它是否w3wp.exe使用 .NET 4.6 使(工作程序)崩潰。我這樣做了,但沒有,所以我懷疑你的程式碼。或者可能是奇怪的伺服器/更新檔級別的緊急問題..這些步驟應該可以幫助您查明它。旁注:即使它不應該影響應用程序程序,我建議修復這些
Response.Redirect()問題。我們最近在一個企業應用程序中這樣做了,是的,這是一個廣泛的變化,但我們不再得到 TAE 例外。修復很簡單:只需呼叫Response.Redirect(false);,然後確保在呼叫該函式後沒有程式碼將執行(return例如呼叫)。這篇文章解釋了