如何在我的应用程序中找到StackOverflowException的来源 [英] How to find the source of a StackOverflowException in my application

查看:36
本文介绍了如何在我的应用程序中找到StackOverflowException的来源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序中的某个地方出现了StackOverFlow-我正在尝试找出跟踪它的方法.

I have a StackOverFlow occurring somewhere in my application - and I'm trying to figure out ways to track it down.

我的事件日志每天都会在崩溃中显示以下信息:

My event logs show a crash every day or so with the following information:

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

Faulting application name: MyApp.exe, version: 1.0.0.0, time stamp: 0x522e8317

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

Faulting module name: clr.dll, version: 4.0.30319.18047, time stamp: 0x515530ce

异常代码:0xc00000fd

Exception code: 0xc00000fd

故障偏移量:0x000000000000c657

Fault offset: 0x000000000000c657

故障进程ID:0x117fc

Faulting process id: 0x117fc

故障排除应用程序开始时间:0x01ceadf607b184d2

Faulting application start time: 0x01ceadf607b184d2

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

Faulting application path: C:\Users\Administrator\Desktop\MyApp.exe

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

Faulting module path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll

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

Report Id: d52424aa-1a16-11e3-bc4b-002590a4ec55

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

I read that 0xc00000fd is a stack overflow, but I am unsure on where it could be occurring (very large codebase), and how to track it down. Any ideas?

推荐答案

这通常是我使用WinDbg进行跟踪的东西,否则只是一个猜谜游戏.这是一个快速的演练,应该为您设定正确的方向.

This is typically something I use WinDbg to track down, otherwise it's just a guessing game. Here's a quick walkthrough that should set you in the right direction.

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

WinDbg is a debugger for Windows, good for debugging managed and unmanaged code. It's also great for examining crash dumps. Let's start with an example program.

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

    [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
    static int IWillStackOverflow(int i)
    {
        return IWillStackOverflow(i + 1);
    }
}

这是一个非常人为的示例,但让我们继续吧.它确实确实发生了堆栈溢出,也没有提供堆栈跟踪.这就是WinDbg的来源.首先,您需要安装它,它是

This is a pretty contrived example, but let's roll with it. It does indeed stack overflow, and nor does it provide a stacktrace. This is where WinDbg comes in. First you need to install it, which is part of the Debugging Tools in the Windows SDK. There are two versions, the x64 and x86. You'll want to run the one that matches the bitness of your application.

在WinDbg中,使用文件"->打开可执行文件"并运行带有WinDbg的可执行文件.应用程序加载后,调试器将立即中断,您可以使用 g 命令转到并使用您的应用程序,直到获得StackOverflowException.不过,在执行此操作之前,请确保您的符号正确-通常运行 .symfix + 可以对其进行更正,然后就可以进行操作.

In WinDbg, use File -> Open Executable and run your executable with WinDbg attached. The debugger will break as soon as your application loads, you can use the g command to Go and use your application until you get a StackOverflowException. Before you do that though, make sure your symbols are correct - usually running .symfix+ will correct it, then you can go.

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

When you get your StackOverflowException, the debugger will break on the thread that raised the exception, and the message will be something like this:

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

(cc0.b00): Stack overflow - code c00000fd (first chance)

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

Now we can load the managed debugging extensions with this command (I am assuming you are using the .NET Framework 4.0 or 4.5 here):

.loadby sos clr

并调用!clrstack .在此示例中,输出为:

And calling !clrstack. In this example, the output is:

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发生时,我们拥有托管堆栈.

So we have our managed stack at the time of the StackOverflowException.

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

If your Application doesn't StackOverflow very easily, you can configure ADPlus to take a memory dump of your application at the time of the StackOverflowException. ADPlus is another big-hammer tool, but it's effective. First you need a configuration for ADPlus, here is an example one:

<ADPlus> 
   <!-- Add log entry, log faulting thread stack and dump full on first chance StackOverflow --> 
<Exceptions> 
     <Config> 
        <!-- Use sov for stack overflow exception --> 
       <Code> sov </Code> 
       <Actions1> Log;Stack;FullDump </Actions1> 
       <!-- Depending on what you intend - either stop the debugger (Q or QQ) or continue unhandled (GN) --> 
       <ReturnAction1> GN </ReturnAction1> 
     < Config> 
  </Exceptions> 
</ADPlus>

此配置示例最初由用户jaskis在MSDN论坛上发布:

This configuration example was originally published by user jaskis on the MSDN Forums: http://blogs.msdn.com/b/jaskis/archive/2010/08/11/cwa-ends-up-with-blank-screen-on-browser-on-iis-7.aspx Then use the command line to start your application with the configuration.

这只是一个示例,WinDbg是一个非常强大的工具,尽管它有一些学习上的困难.互联网上有很多很好的资源可以帮助您一臂之力. Tess Ferrandez 在她的博客中有许多文章介绍了WinDbg和托管的调试扩展.

This is just an example, WinDbg is a very powerful tool, though it has a bit of a learning curve. There are a lot of good resources on the internet for getting the hang of it. Tess Ferrandez has many articles in her blog that cover WinDbg and the managed debugging extensions.

这篇关于如何在我的应用程序中找到StackOverflowException的来源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆