Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在我的应用程序中找到StackOverflowException的源_C#_.net - Fatal编程技术网

C# 如何在我的应用程序中找到StackOverflowException的源

C# 如何在我的应用程序中找到StackOverflowException的源,c#,.net,C#,.net,我的应用程序中的某个地方发生了堆栈溢出,我正在设法找到跟踪它的方法 我的事件日志显示每天左右都有一次崩溃,其中包含以下信息: 故障应用程序名称:MyApp.exe,版本:1.0.0.0,时间戳:0x522e8317 故障模块名称:clr.dll,版本:4.0.30319.18047,时间戳:0x515530ce 异常代码:0xc00000fd 故障偏移量:0x000000000000c657 出错进程id:0x117fc 故障应用程序启动时间:0x01ceadf607b184d2 出现故障的应用

我的应用程序中的某个地方发生了堆栈溢出,我正在设法找到跟踪它的方法

我的事件日志显示每天左右都有一次崩溃,其中包含以下信息:

故障应用程序名称:MyApp.exe,版本:1.0.0.0,时间戳:0x522e8317

故障模块名称:clr.dll,版本:4.0.30319.18047,时间戳:0x515530ce

异常代码:0xc00000fd

故障偏移量:0x000000000000c657

出错进程id:0x117fc

故障应用程序启动时间:0x01ceadf607b184d2

出现故障的应用程序路径:C:\Users\Administrator\Desktop\MyApp.exe

故障模块路径:C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll

报告Id:d52424aa-1a16-11e3-bc4b-002590a4ec55


我读到0xc00000fd是堆栈溢出,但我不确定它可能发生在哪里(非常大的代码基),以及如何跟踪它。有什么想法吗?

这通常是我使用WinDbg来追踪的,否则这只是一个猜测游戏。下面是一个快速的演练,它将为您指明正确的方向

WinDbg是Windows的调试器,适用于调试托管和非托管代码。它对于检查崩溃转储也很有用。让我们从一个示例程序开始

class Program
{
    static void Main(string[] args)
    {
        IWillStackOverflow(0);
    }

    [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
    static int IWillStackOverflow(int i)
    {
        return IWillStackOverflow(i + 1);
    }
}
这是一个相当做作的例子,但让我们继续。它确实存在堆栈溢出,也不提供堆栈跟踪。这就是WinDbg的用武之地。首先需要安装它,这是中调试工具的一部分。有两个版本,x64和x86。您需要运行与应用程序位匹配的程序

在WinDbg中,使用文件->打开可执行文件,并在连接WinDbg的情况下运行可执行文件。一旦应用程序加载,调试器就会中断,您可以使用
g
命令继续使用应用程序,直到获得StackOverflowException。但在执行此操作之前,请确保符号正确-通常运行
。symfix+
将对其进行更正,然后您可以继续

当您获得StackOverflowException时,调试器将在引发异常的线程上中断,消息如下:

(cc0.b00):堆栈溢出-代码c00000fd(第一次机会)

现在我们可以用这个命令加载托管调试扩展(我假设您在这里使用的是.NET Framework 4.0或4.5):

并呼叫
!clrstack
。在本例中,输出为:

000000d440c76040 00007ffb282b0111 StackOverflower.Program.IWillStackOverflow(Int32) [Program.cs @ 20]
000000d440c76080 00007ffb282b0111 StackOverflower.Program.IWillStackOverflow(Int32) [Program.cs @ 20]
000000d440c760c0 00007ffb282b0111 StackOverflower.Program.IWillStackOverflow(Int32) [Program.cs @ 20]
..Repeat thousands of times..
因此,在StackOverflowException发生时,我们有了托管堆栈

如果您的应用程序不太容易发生StackOverflow,您可以配置在StackOverflowException发生时对应用程序进行内存转储。ADPlus是另一个大锤工具,但它很有效。首先,您需要ADPlus的配置,下面是一个示例:


然后使用命令行以配置启动应用程序



这只是一个例子,WinDbg是一个非常强大的工具,尽管它有一点学习曲线。在互联网上有很多很好的资源可以让你掌握它的窍门。在她的博客中有许多文章介绍了WinDbg和托管调试扩展。

这已经得到了回答,但我正在受影响的机器上搜索比
WinDbg
更好的答案,因为这只发生在我不想安装
WinDbg
的生产服务器机器上。我发现它指的是一个可从微软下载的工具,它允许你在每个异常代码的基础上配置系统应该如何响应不同的异常。这将(希望)允许在不同于生产机器的机器上进行调试:


DebugDiag
实用程序可配置为在发生
StackOverflowException
时生成崩溃转储。下载它。

你还有其他的应用程序级日志记录吗?我的第一个猜测是一些导致无限循环或大量递归的情况。这可能会很痛苦,但你可以尝试手动检查每个
,而
,关于循环注释:无限循环很可能永远不会导致堆栈溢出。递归几乎肯定是原因。使用WinDbg+SOS是确定发生了什么的最简单方法。将ADPlus设置为在进程崩溃时进行小型转储,并检查转储以了解发生了什么情况。我希望您能将您的评论转化为答案,我也不想自己写这篇文章:)。唯一缺少的是如何设置在崩溃时获取程序的小型转储,以及如何将其加载到WinDbg,而不是在调试器中运行程序,OP说它每天崩溃一次,所以调试器必须连接很长一段时间才能看到它。为了进一步阅读,我发现要让你的C#代码在崩溃时生成转储,以及如何在中打开它WinDbg@ScottChamberlain我添加了一些关于ADPlus的信息,希望足够有用。谢谢你的反馈。谢谢你的回答。我必须根据调整sos加载,并确保以管理员身份运行,但这一切都使我能够了解我的EF的底部,因此错误:-)
000000d440c76040 00007ffb282b0111 StackOverflower.Program.IWillStackOverflow(Int32) [Program.cs @ 20]
000000d440c76080 00007ffb282b0111 StackOverflower.Program.IWillStackOverflow(Int32) [Program.cs @ 20]
000000d440c760c0 00007ffb282b0111 StackOverflower.Program.IWillStackOverflow(Int32) [Program.cs @ 20]
..Repeat thousands of times..