C# 在WebService(ASP.NET)中获取StackOverflowException
我有一个名为ECService.asmx的Web服务,其中包含230多个WebMethods。 当我将这些方法分成几个“asmx”或注释掉一半代码时,StackOverflowException将不再发生 根据MSDN: 当执行堆栈因嵌套方法调用过多而溢出时,将引发StackOverflowException异常 我很确定我没有任何递归方法。 它们所做的只是在调用时返回一个数据集,仅此而已 所以我做了一些研究,并确信使用任何工具来提取进程的完整用户转储(iisexpress),然后使用windbg工具来检查记录在其中的堆栈树。我尝试使用Visual Studio 2017的选项“调试>将转储另存为…”捕获完整的用户转储: 然后我得到了这个C# 在WebService(ASP.NET)中获取StackOverflowException,c#,asp.net,stack-overflow,asmx,windbg,C#,Asp.net,Stack Overflow,Asmx,Windbg,我有一个名为ECService.asmx的Web服务,其中包含230多个WebMethods。 当我将这些方法分成几个“asmx”或注释掉一半代码时,StackOverflowException将不再发生 根据MSDN: 当执行堆栈因嵌套方法调用过多而溢出时,将引发StackOverflowException异常 我很确定我没有任何递归方法。 它们所做的只是在调用时返回一个数据集,仅此而已 所以我做了一些研究,并确信使用任何工具来提取进程的完整用户转储(iisexpress),然后使用windb
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+相关进程的崩溃规则”从未触发。我做错了吗?如果我遗漏了什么,我想提供更多的信息
(请原谅,由于业务敏感性,我可能无法包含完整的文件。现在我在一家商业公司实习,经理要求我不能使用任何机械解决方法来忽略这个问题。)
研究参考:
我现在没有可用的.NET堆栈溢出崩溃转储,但这是我的内存:
!线程
命令应列出.NET线程。如果线程上存在异常,则该线程的“异常”列中应该有一个指示符。使用~s
切换到该线程,然后使用!clrstack
它也应该在本机端工作,因为.NET异常也是正常的SEH异常。如果使用navctivethreads命令~
,则应该有一个线程标记为#
,这表示线程出现异常。如果看不到,则可能是活动线程,因为活动线程指示符
覆盖异常指示符。在任何情况下,您都应该能够使用~#s
切换到线程(不使用数字替换#)
堆栈空间是否真的耗尽了,应该可以使用
来确定!teb
命令并查看堆栈底部和堆栈限制。然后将其与堆栈指针(ESP寄存器)进行比较。我现在没有可用的.NET堆栈溢出崩溃转储,但我的内存如下:
!线程
命令应列出.NET线程。如果线程上存在异常,则该线程的“异常”列中应该有一个指示符。使用~s
切换到该线程,然后使用!clrstack
它也应该在本机端工作,因为.NET异常也是正常的SEH异常。如果使用navctivethreads命令~
,则应该有一个线程标记为#
,这表示线程出现异常。如果看不到,则可能是活动线程,因为活动线程指示符
覆盖异常指示符。在任何情况下,您都应该能够使用~#s
切换到线程(不使用数字替换#)
堆栈空间是否真的耗尽了,应该可以使用
来确定!teb
命令并查看堆栈底部和堆栈限制。然后将其与堆栈指针(ESP regizer)进行比较。tt自从我使用SOS以来已经有一段时间了,但是CLRStack将只转储当前线程。尝试EEStack-EE,看看它给了你什么-它将转储所有线程的堆栈跟踪,你应该能够看到哪个方法已经包装了自己analyze-v
在有问题的线程上设置线程上下文。从那里你可以使用!CLRStack@AdamBenson!EEStack-EE
确实像您所说的那样转储所有线程,但是我没有识别出有问题的线程。您提供的参考非常有用,感谢您的快速评论@利文基尔斯马科斯。上面写着FAILURE\u FUNCTION\u NAME:domainneutralistubclass.IL\u STUB\u PInvoke
,所以我想我应该从这里开始调查,不是吗?谢谢我已经有一段时间没有使用SOS了,但是CLRStack只会转储当前线程。尝试EEStack-EE,看看它给了你什么-它将转储所有线程的堆栈跟踪,你应该能够看到哪个方法已经包装了自己analyze-v
在有问题的线程上设置线程上下文。从那里你可以使用!CLRStack@AdamBenson!EEStack-EE
确实像您所说的那样转储所有线程,但是我没有识别出有问题的线程。您提供的参考非常有用,感谢您的快速评论@利文基尔斯马科斯。上面写着FAILURE\u FUNCTION\u NAME:domainneutralistubclass.IL\u STUB\u PInvoke
,所以我想我应该从这里开始调查,不是吗?谢谢谢谢你详尽的回答。我已成功打印线程的堆栈跟踪。然而,你提到的“ESP注册”这个词对我来说相当陌生。我还没有学过汇编语言或类似的东西。无论如何,我接受这是最好的答案,尽管我仍然无法找出背后的真正原因。谢谢你详尽的回答。我已成功打印线程的堆栈跟踪。然而,你提到的“ESP注册”这个词对我来说相当陌生。我还没有学过汇编语言或类似的东西。无论如何,我接受这是最好的答案,尽管我仍然无法找出背后的真正原因。
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]