【问题标题】:How do I disable the Visual C++ Runtime Error in a Web Server?如何禁用 Web 服务器中的 Visual C++ 运行时错误?
【发布时间】:2012-10-28 01:51:33
【问题描述】:

在 Windows Server 2003 计算机上运行 WCF 的生产 Web 服务没有响应。我在DebugDiag 1.2中捕获了一个内存转储文件进行分析。

DebugDiag 显示线程遇到 OutOfMemoryException。通常,我们会尝试捕获所有异常,将它们打印到事件日志中,然后将它们作为 WCF 错误返回。

这个 OutOfMemoryException 不知何故未被捕获并导致 C++ 错误。我接受 .NET 运行时无法处理此错误。当你内存不足时,你就内存不足。

分析显示其中一个线程试图显示 Visual C++ 运行时错误:

Microsoft Visual C++ 运行时库运行时错误!程序:C:\windows\system32\inetsrv"。

堆栈跟踪如下所示:

ntdll!KiFastSystemCallRet    
ntdll!ZwRaiseHardError+c    
user32!ServiceMessageBox+145    
user32!MessageBoxWorker+13e    
user32!MessageBoxTimeoutW+7a    
user32!MessageBoxTimeoutA+9c    
user32!MessageBoxExA+1b    
user32!MessageBoxA+45    
msvcr71!__crtMessageBoxA+f4   f:\vs70builds\3052\vc\crtbld\crt\src\crtmbox.c @ 118 + 10 
msvcr71!_NMSG_WRITE+12e  f:\vs70builds\3052\vc\crtbld\crt\src\crt0msg.c @ 240 + 10 
msvcr71!abort+7   f:\vs70builds\3052\vc\crtbld\crt\src\abort.c @ 48 
kernel32!UnhandledExceptionFilter+12a    
kernel32!BaseThreadStart+4a    
kernel32!_except_handler3+61    
ntdll!ExecuteHandler2+26    
ntdll!ExecuteHandler+24    
ntdll!RtlRaiseException+3d    
kernel32!RaiseException+53    
msvcr80!_CxxThrowException+46    
mscorwks!ThrowOutOfMemory+24 

abort 的文档说:

在基于 Windows 的单线程或多线程应用程序中,中止调用 Windows MessageBox 函数创建一个消息框来显示 带有 OK 按钮的消息。当用户单击确定时,程序中止 立即地。可以通过调用来抑制消息 _set_abort_behavior 带有适当的参数。

此消息框挂起服务器。一个线程触发了 GC,但该线程禁用了抢占式 GC。其余大部分线程在等待 GC 完成时阻塞。

我如何为网络服务器disable the Visual C++ Runtime Error dialog

-- 编辑--

OutOfMemoryException 是在处理大型数据集的一个线程中引发的。一旦抛出这个,就会抛出一个跨上下文异常。这导致了 WinDbg 中的以下堆栈跟踪:

1c54eee8 78158e89 e06d7363 00000001 00000003 kernel32!RaiseException+0x53 (FPO: [Non-Fpo])
1c54ef20 7a14fd18 1c54ef30 7a37d92c 7a3c4aa8 **msvcr80**!_CxxThrowException+0x46 (FPO: [Non-Fpo])
1c54ef34 7a1082db f74a69a8 79f38888 1c54f108 mscorwks!ThrowOutOfMemory+0x24 (FPO: [Non-Fpo])
1c54f060 7a10a245 00000000 1c54f098 1c54f108 mscorwks!Thread::RaiseCrossContextException+0x408 (FPO: [Non-Fpo])
1c54f114 79fd882b 00000002 79fd87f6 1c54f20c mscorwks!Thread::DoADCallBack+0x2a2 (FPO: [Non-Fpo])
1c54f130 79e9846b 1c54f20c 1c54f1b8 79f7762b mscorwks!Thread::DoADCallBack+0x310 (FPO: [Non-Fpo])
1c54f1c4 79e98391 1c54f20c f74a6bc8 23e78e00 mscorwks!Thread::ShouldChangeAbortToUnload+0xe3 (FPO: [Non-Fpo])
1c54f200 79e9851d 1c54f20c 00000002 00000000 mscorwks!Thread::ShouldChangeAbortToUnload+0x30a (FPO: [Non-Fpo])
1c54f228 79fd8f6c 00000002 7a0b68a2 1c54f264 mscorwks!Thread::ShouldChangeAbortToUnload+0x33e (FPO: [Non-Fpo])
1c54f240 7a0b6b5b 00000002 7a0b68a2 1c54f264 mscorwks!ManagedThreadBase::ThreadPool+0x13 (FPO: [Non-Fpo])
1c54f294 7a0b6b8d 00000000 00000000 04a47fe0 mscorwks!BindIoCompletionCallbackStubEx+0x95 (FPO: [Non-Fpo])
1c54f2ac 79f3e605 00000000 00000000 04a47fe0 mscorwks!BindIoCompletionCallbackStub+0x13 (FPO: [Non-Fpo])
1c54f314 79f920a5 00000000 00000000 7ffdc000 mscorwks!ThreadpoolMgr::CompletionPortThreadStart+0x430 (FPO: [Non-Fpo])
1c54ffb8 77e64829 23e29018 00000000 00000000 mscorwks!Thread::intermediateThreadProc+0x49 (FPO: [Non-Fpo])
1c54ffec 00000000 79f9205f 23e29018 00000000 kernel32!BaseThreadStart+0x34 (FPO: [Non-Fpo])

并且那个异常导致调用运行时来显示这条消息:

1c54e340 7c82775b 773d7a4b 50000018 00000004 ntdll!KiFastSystemCallRet
1c54e344 773d7a4b 50000018 00000004 00000003 ntdll!NtRaiseHardError+0xc
1c54e3a0 773b8377 1d05ff70 1d052e48 00012010 user32!ServiceMessageBox+0x145
1c54e4fc 7739eec9 1c54e508 00000028 00000000 user32!MessageBoxWorker+0x13e
1c54e554 773d7d0d 00000000 1d05ff70 1d052e48 user32!MessageBoxTimeoutW+0x7a
1c54e588 773c42c8 00000000 1c54e62c 7c37f480 user32!MessageBoxTimeoutA+0x9c
1c54e5a8 773c42a4 00000000 1c54e62c 7c37f480 user32!MessageBoxExA+0x1b
1c54e5c4 7c34c224 00000000 1c54e62c 7c37f480 user32!MessageBoxA+0x45
1c54e5f8 7c348e6c 1c54e62c 7c37f480 00212010 msvcr71!__crtMessageBoxA+0xf4 [f:\vs70builds\3052\vc\crtbld\crt\src\crtmbox.c @ 118]
1c54e81c 7c34cf83 0000000a 00000000 1c54ead4 msvcr71!_NMSG_WRITE+0x12e [f:\vs70builds\3052\vc\crtbld\crt\src\crt0msg.c @ 240]
1c54e854 77e761b7 1c54ead4 00000000 00000000 msvcr71!abort+0x7 [f:\vs70builds\3052\vc\crtbld\crt\src\abort.c @ 48]
1c54eaac 77e792a3 1c54ead4 77e61ac1 1c54eadc kernel32!UnhandledExceptionFilter+0x12a
1c54eab4 77e61ac1 1c54eadc 00000000 1c54eadc kernel32!BaseThreadStart+0x4a
1c54eadc 7c828752 1c54ee98 1c54ffdc 1c54ebb8 kernel32!_except_handler3+0x61
1c54eb00 7c828723 1c54ee98 1c54ffdc 1c54ebb8 ntdll!ExecuteHandler2+0x26
1c54eba8 7c82863c 1c549000 1c54ebb8 00010007 ntdll!ExecuteHandler+0x24
1c54ee88 77e4bee7 1c54ee98 00000002 e06d7363 ntdll!RtlRaiseException+0x3d
1c54eee8 78158e89 e06d7363 00000001 00000003 kernel32!RaiseException+0x53

我不确定为什么堆栈上有两个版本的 Visual Studio 运行时库。这是不寻常的。我没有看到堆栈中存在其他 3rd 方 DLL 的证据。

【问题讨论】:

  • 这是栈顶吗?谁在打电话给mscorwks!ThrowOutOfMemory?听起来您可能正在调用一些不打算在服务应用程序中使用的代码。
  • 不是,那是OutOfMemoryException产生C++运行时异常后的调用栈。 OutOfMemoryException 的来源是加载到内存中的几个非常大的 DataSet。那是一个单独的问题。我想防止网络服务因此类错误而挂起。
  • 你的意思是有一个 .NET System.OutOfMemoryException 吗?为什么会生成 C++ 运行时异常?这是一个 C++ 应用程序吗?
  • 这是一个 .NET WCF 应用程序,它试图将大型 DataSet 加载到内存中并将其返回给客户端。 (我们确实使用 WCF 流,但由于某种原因这里没有使用它。)DataSet 导致抛出 .NET OutOfMemoryException。不知何故,这个 OutOfMemoryException 被作为 C++ 错误抛出。进程使用调用 abort() 的 UnhandledExceptionFilter 捕获了这一点,并且 abort 试图弹出 C++ 运行时错误消息框。
  • 如果我是你,我会找出那个 C++ 异常来自哪里。为什么还有 C++ 运行时?

标签: c# wcf web-services error-handling windows-server-2003


【解决方案1】:

您必须在程序集中调用 Win32 设置中止行为。您可以使用 P/Invoke 来执行此操作。

这是一篇关于类似问题的有趣文章。 http://blogs.msdn.com/b/pfedev/archive/2010/08/25/whodunit-who-threw-the-message-box-and-why.aspx

他们认为这是一个尚未解决的已知问题,因此建议使用 _set_abort_behavior 将其关闭。

【讨论】:

  • 我相信这是正确的答案。我不确定在哪里调用这个——也许在一个静态构造函数中。我还发现我们可以覆盖这样的崩溃系统行为:support.microsoft.com/kb/124873。我向客户推荐他们现在在他们的 Web 服务器上设置 ErrorMode = 2。
  • @PaulWilliams 您是否能够确认注册表项设置适用于您的所有案例?这是一个很好的发现。
  • 在我的情况下,注册表项设置不起作用。我们的 w3wp 进程仍然以问题描述的方式挂起。
猜你喜欢
  • 1970-01-01
  • 2012-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-18
  • 2021-03-04
  • 1970-01-01
  • 2016-06-22
相关资源
最近更新 更多