我有一个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.
答案 0 :(得分:1)
在异常时使用任务管理器进行转储不是很可靠。请尝试使用SysInternals ProcDump -e -ma -x "my.exe" "my.dmp"
或将Windows错误报告配置为create local dumps(将转储类型设置为2 / full)。
一旦你有一个好的转储,Visual Studio应该在打开转储后在字段Exception code
中显示一些内容。我想你现场看起来像我一样空洞(见截图)。
如果转储正常,它应该有一个异常代码:
答案 1 :(得分:0)
首先,您的代码没有任何try catch语句。当您的代码崩溃时,它会将异常发送到上层处理程序。在您的代码中,最新的处理程序是Main void本身,这就是您看到该部分的原因。
此外,您不需要原生符号。本机符号是COM DLL文件,在此示例中您不需要。
答案 2 :(得分:0)
找到解决我问题的方法。实际上有两个问题:
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"