【问题标题】:Getting StackOverflowException in WebService (ASP.NET)在 WebService (ASP.NET) 中获取 StackOverflowException
【发布时间】:2017-07-13 10:38:59
【问题描述】:

我有一个名为 ECService.asmx 的 WebService,其中包含 230 多个 WebMethod。 当我将这些方法分成几个“asmx”或注释掉一半代码时,StackOverflowException 将不再发生。

根据 MSDN:

当执行堆栈因嵌套方法调用过多而溢出时,将引发 StackOverflowException 异常。

我很确定我没有任何递归方法。 他们所做的只是在调用时返回一个数据集,仅此而已。

所以我做了一些研究,并确信使用任何工具来提取进程的完整用户转储 (iisexpress),然后使用 windbg 工具检查其中登录的堆栈树。我尝试使用 Visual Studio 2017 的选项“Debug> Save Dump As...”来捕获完整的用户转储:

kbn
.loadby sos clr
!CLRStack

然后我得到了这个

0:033> !CLRStack
OS Thread Id: 0x584 (33)
Child SP       IP Call Site
06b625a8 77a21d3c [FaultingExceptionFrame: 06b625a8] 
06b9ef00 77a21d3c [InlinedCallFrame: 06b9ef00] 
06b9f540 77a21d3c [InlinedCallFrame: 06b9f540] 
06b9f53c 65cce181 DomainNeutralILStubClass.IL_STUB_PInvoke(IntPtr, System.Web.RequestNotificationStatus ByRef)
06b9f540 65c7b892 [InlinedCallFrame: 06b9f540] System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr, System.Web.RequestNotificationStatus ByRef)
06b9f574 65c7b892 System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)
06b9f578 65c7b39f [InlinedCallFrame: 06b9f578] 
06b9f670 65c7b39f System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)
06b9f748 05aeeb10 [ContextTransitionFrame: 06b9f748] 

但我几乎没有发现任何与 StackOverflowException 相关的内容。老实说,我已经不知道该做什么了……

我也尝试使用调试诊断工具来捕获完整的转储,但是我设置的规则“所有 IIS/COM+ 相关进程的崩溃规则”从未被触发。我做错了吗?如果我遗漏了什么,我想提供更多信息。

(请原谅,由于业务敏感性,我可能无法包含完整的文件。现在我在一家商业公司实习,经理问我不能通过使用任何机械变通方法来忽略这个问题。)

研究参考:

exception code: 0xc00000fd. Debugging a StackOverflowException

Using windbg to solve problems

【问题讨论】:

  • tt 自从我使用 SOS 以来已经有一段时间了,但 CLRStack 只会转储当前线程。试试 !EEStack -EE 看看它给了你什么——它会转储所有线程的堆栈跟踪,你应该能够看到哪个方法被自己包裹住了。 docs.microsoft.com/en-us/dotnet/framework/tools/…
  • analyze -v 在有问题的线程上设置线程上下文。从那里你可以使用 !CLRStack。
  • @AdamBenson !EEStack -EE 确实像你说的那样转储了所有线程,但我未能识别出有问题的线程。您提供的参考很有帮助,感谢您的快速评论! @LievenKeersmaekers。上面写着FAILURE_FUNCTION_NAME: DomainNeutralILStubClass.IL_STUB_PInvoke full result 所以我想我应该从这里开始调查,不是吗?谢谢!

标签: c# asp.net stack-overflow asmx windbg


【解决方案1】:

我现在没有可用的 .NET 堆栈溢出故障转储,但这是我的记忆:

!threads 命令应该列出 .NET 线程。如果线程发生异常,该线程应该在“异常”列中有一个指示符。使用~<number>s 切换到该线程,然后使用!clrstack

它也应该在本机端工作,因为 .NET 异常也是正常的 SEH 异常。如果使用navtive threads 命令~,应该有一个线程标有#,表示有异常线程。如果您看不到,则可能是活动线程,因为活动线程指示器. 覆盖了异常指示器。在任何情况下,您都应该能够使用~#s(字面意思是不要用数字替换#)切换到例外的线程。

堆栈空间是否真的耗尽,应该可以使用!teb 命令并查看堆栈基础和堆栈限制来确定。然后将其与堆栈指针(ESP 寄存器)进行比较。

【讨论】:

  • 感谢您的详尽回答。我设法打印了线程的堆栈跟踪。 (Screenshot) 但是,你提到的“ESP 寄存器”这个词对我来说很陌生。我还没有学过汇编语言或类似的东西。无论如何,我接受这是最好的答案,尽管我仍然无法弄清楚其背后的真正原因。
猜你喜欢
  • 2021-10-12
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多