【问题标题】:Finding crash location based on crash dump根据故障转储查找故障位置
【发布时间】:2014-05-12 17:53:01
【问题描述】:

我有一个 C# WPF 应用程序,并且正在尝试找出一种方法来使用转储文件在 Visual Studio 2010 中查明崩溃位置。我正在使用 SysWow64\TaskMgr.exe 来获取我的崩溃转储500MB。

这是我的启动代码,它使用 Visual Basic 解决方法来确保我只运行一个实例。

using System;
using Microsoft.VisualBasic.ApplicationServices;

namespace UselessCrashDump
{
    public class Startup
    {
        [STAThread]
        public static void Main(string[] args)
        {
            SingleInstanceManager singleInstanceManager = new SingleInstanceManager();
            singleInstanceManager.Run(args);
        }
    }

    // Using VB bits to detect single instances and process accordingly:
    //  * OnStartup is fired when the first instance loads
    //  * OnStartupNextInstance is fired when the application is re-run again    
    public class SingleInstanceManager : WindowsFormsApplicationBase
    {
        App _app;

        public SingleInstanceManager()
        {
            this.IsSingleInstance = true;
        }

        protected override bool OnStartup(Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e)
        {
            //first launch
            _app = new App();
            _app.InitializeComponent();
            _app.Run();

            return false;
        }

        protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
        {
            //subsequent launches
            base.OnStartupNextInstance(eventArgs);
            _app.Activate();
        }
    }
}

现在我在我的应用程序中添加了一段代码,它会在我按下按钮后故意让它崩溃。代码如下所示:

private void _crash_Click(object sender, RoutedEventArgs e)
{
   CrashMe(null);          
}

private void CrashMe(string someString)
{
   someString.Split(' ');
}

果然,在我运行exe并单击按钮后,程序崩溃了。然后我获取故障转储,打开它,这就是我看到的:

我期待代码在崩溃的特定位置中断。但是,故障转储指向程序的入口点。所有崩溃都会发生这种情况。我想查看崩溃的确切位置,以及它在调试会话期间发生的方式。

我做错了什么?转储文件本身似乎正在加载 PDB 文件,至少从输出来看:

'[MyApp].DMP' (Managed): Loaded 'C:\Program Files (x86)\[MyCompany]\[MyApp].exe', Symbols loaded.

它似乎没有加载本机符号,但我想既然它是一个托管应用程序,我不需要它们:

'[MyApp].DMP': Loaded 'C:\Program Files (x86)\[MyCompany]\[MyApp].exe', No native symbols in symbol file.

【问题讨论】:

    标签: c# wpf crash-dumps


    【解决方案1】:

    在异常时使用任务管理器进行转储不是很可靠。改用SysInternals ProcDump-e -ma -x "my.exe" "my.dmp" 或将Windows 错误报告配置为create local dumps(将转储类型设置为2 / 完整)。

    一旦你有一个好的转储,Visual Studio 应该在打开转储后在字段Exception code 中显示一些东西。我猜你的字段现在看起来很空,就像我的一样(见截图)。

    如果转储没问题,里面应该有异常代码:

    【讨论】:

      【解决方案2】:

      首先,您的代码没有任何 try catch 语句。当您的代码崩溃时,它会将异常发送到上层处理程序。在您的代码中,最新的处理程序是 Main void 本身,这就是您看到该部分的原因。

      此外,您不需要原生符号。本机符号是本示例中不需要的 COM DLL 文件。

      【讨论】:

      • Main 方法是 .NET 代码,没有异常处理程序。如果异常冒泡,则由操作系统处理。但即使在这种情况下,您也可以看到异常的调用堆栈。如果这不可能,我们怎么能在没有 try/catch 语句的情况下进行调试?
      • @ThomasW。我不认为我说的和你不同。我通过看他的截图回答了他的问题。如果你在他的 Visual Studio 上看到那个绿色标记,你可以看到异常发生在其他地方,但它在 Main 方法的最后冒泡了。另外,我不是说没有try/catch语句就看不到异常。
      • Main 方法中没有发生异常。 Main 方法中的代码是在进行转储时执行的,这只是偶然发生的。看我上面的截图。一点也不例外。
      • @ThomasW。我同意你的看法。有可能得到一个坏的转储。无论如何感谢您的反馈。
      【解决方案3】:

      找到了我的问题的解决方案。实际上有两个问题:

      1) 原来使用任务管理器生成的转储文件不包含异常信息(本文中注明:http://blogs.msdn.com/b/debugger/archive/2009/12/30/what-is-a-dump-and-how-do-i-create-one.aspx

      2) 为了解决问题 #1,我尝试在它崩溃后使用 procdump 应用程序来获取我的转储,但这也没有用,并且指向 Run() 中某处的代码。修复结果是使用 procdump 启动应用程序并在崩溃时写入崩溃转储。这终于解决了问题,打开故障转储让我直接看到了有问题的代码行。我使用的 procdump 命令是:

      procdump -e -ma -x dump.dmp "C:\Program Files(86)\My Company\MyApp.exe"
      

      【讨论】:

      • 几乎同时回答。我认为您应该将参数切换为 -x:首先是 EXE,然后是 DMP。
      • 我在网上的几个文档中第一次看到exe,但是它不起作用,它只是吐出'usage:'提示,提示如下: | -x ,所以至少在我的procdump(v6.00)版本中,转储文件首先出现。
      猜你喜欢
      • 2015-06-11
      • 2016-09-09
      • 2021-05-02
      • 2016-03-21
      • 1970-01-01
      • 1970-01-01
      • 2010-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多