WPF程序启动崩溃:如何调试
本文关键字:调试 何调试 程序 启动 崩溃 WPF | 更新日期: 2023-09-27 18:11:34
我有一个在开发PC和客户PC上运行良好的WPF程序1。但在客户端PC 2上,它在启动时立即崩溃,并弹出"向微软发送报告"窗口。我希望能得到一些关于如何追踪错误的建议。以下是我尝试过的:
-
在主窗口类中插入try-catch:
public MainWindow() { try { MessageBox.Show("Before InitComp()"); InitializeComponent(); MessageBox.Show("Before Sub1()"); Subroutine1(); MessageBox.Show("Before Sub2()"); Subroutine2(); ... etc ... } catch (Exception ex) { ... code for MessageBox display error here ... } }
这个想法是试图隔离启动序列的哪个部分正在崩溃,但第一个调试消息"在InitComp()之前"甚至没有出现。所以似乎应用程序甚至在开始我的代码之前就崩溃了。
- 一种可能是在客户端PC 2中安装整个VS2008,加载源代码并使用IDE调试器跟踪问题。这可能是发现问题最有效的方法。但我不想这样做,因为a)客户端PC 2不属于我,b)它不能扩展:我必须为客户端PC 3/4/5/…c)它违反了我公司的VS2008许可证。
我应该如何调试这个问题?
在App.xaml页眉中添加:
<Application DispatcherUnhandledException="App_DispatcherUnhandledException" />
,并在app . example .cs中添加如下内容:
void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs args)
{
log.Fatal("An unexpected application exception occurred", args.Exception);
MessageBox.Show("An unexpected exception has occurred. Shutting down the application. Please check the log file for more details.");
// Prevent default unhandled exception processing
args.Handled = true;
Environment.Exit(0);
}
老派方法:像这样的严重崩溃可能会冒气泡出来,你可以通过Windows中的事件查看器看到。你查过了吗?很多时候,这不会给我带来任何额外的麻烦。
下载ProcDump
。输入"procdump -t -w app.exe ...
"或"procdump -e -w app.exe ...
"。也可以探索其他旗帜。然后在你最喜欢的调试器(Visual Studio/WinDbg)中打开转储文件,查看堆栈跟踪。
跟踪/日志非常强大,特别是当问题发生在客户身上时。您不能总是调试,并且转储可能无法提供导致这一点的完整视图。它绝对是对转储或调试的补充。
你也可以打开和关闭它,甚至切换电平。
DebugView是一个很好的跟踪程序:
http://technet.microsoft.com/en-us/sysinternals/bb896647 跟踪:http://msdn.microsoft.com/en-us/library/3at424ac.aspx 例如,下面是一个可切换级别的跟踪类示例:using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Globalization;
using System.Threading;
namespace Sample
{
public class Tracer
{
//
// supports holding many trace switches.
//
static Dictionary<string, TraceSwitch> s_switches = new Dictionary<string, TraceSwitch>();
static TraceSwitch s_switch = new TraceSwitch("trace", "Default tracing switch");
static object s_locker = new object();
private static TraceSwitch GetSwitch (string category)
{
// only pay the lock penalty if it doesn't exist
if (!s_switches.ContainsKey (category))
{
lock (s_locker)
{
if (!s_switches.ContainsKey (category))
{
TraceSwitch traceSwitch = new TraceSwitch(category,
String.Format("Tracing switch for category '{0}'", category));
s_switches.Add (category, traceSwitch);
}
}
}
return s_switches[category];
}
//
// No level overloads
//
public static void Output(string message)
{
WriteLine("None", TraceLevel.Info, message);
}
public static void OutputIf(bool condition, string message)
{
if (condition)
{
Output(message);
}
}
public static void Output(string format, params object[] args)
{
Debug.Assert(format != null);
Output(string.Format(CultureInfo.InvariantCulture, format, args));
}
public static void OutputIf(bool condition, string format, params object[] args)
{
if (condition)
{
Output(format, args);
}
}
//
// Error level overloads
//
public static void Error(string message)
{
if (s_switch.TraceError)
{
WriteLine(String.Empty, TraceLevel.Error, message);
}
}
public static void Error(string category, string message)
{
if (GetSwitch(category).TraceError)
{
WriteLine(category, TraceLevel.Error, message);
}
}
public static void ErrorIf(bool condition, string message)
{
if (condition)
{
Error(message);
}
}
public static void ErrorIf(string category, bool condition, string message)
{
if (condition)
{
Error(category, message);
}
}
public static void Error(string format, params object[] args)
{
Debug.Assert(format != null);
Error(string.Format(CultureInfo.InvariantCulture, format, args));
}
public static void Error(string category, string format, params object[] args)
{
Debug.Assert(format != null);
Error(category, string.Format(CultureInfo.InvariantCulture, format, args));
}
public static void ErrorIf(bool condition, string format, params object[] args)
{
if (condition)
{
Error(format, args);
}
}
public static void ErrorIf(string category,
bool condition,
string format,
params object[] args)
{
if (condition)
{
Error(category, format, args);
}
}
//
// Warning level overloads
//
public static void Warning(string message)
{
if (s_switch.TraceWarning)
{
WriteLine(String.Empty, TraceLevel.Warning, message);
}
}
public static void Warning(string category, string message)
{
if (GetSwitch(category).TraceWarning)
{
WriteLine(category, TraceLevel.Warning, message);
}
}
public static void WarningIf(bool condition, string message)
{
if (condition)
{
Warning(message);
}
}
public static void WarningIf(string category, bool condition, string message)
{
if (condition)
{
Warning(category, message);
}
}
public static void Warning(string format, params object[] args)
{
Debug.Assert(format != null);
Warning(string.Format(CultureInfo.InvariantCulture, format, args));
}
public static void Warning(string category, string format, params object[] args)
{
Debug.Assert(format != null);
Warning(category, string.Format(CultureInfo.InvariantCulture, format, args));
}
public static void WarningIf(bool condition, string format, params object[] args)
{
if (condition)
{
Warning(format, args);
}
}
public static void WarningIf(string category,
bool condition,
string format,
params object[] args)
{
if (condition)
{
Warning(category, format, args);
}
}
//
// Info level overloads
//
public static void Info(string message)
{
if (s_switch.TraceInfo)
{
WriteLine(String.Empty, TraceLevel.Info, message);
}
}
public static void Info(string category, string message)
{
if (GetSwitch(category).TraceInfo)
{
WriteLine(category, TraceLevel.Info, message);
}
}
public static void InfoIf(bool condition, string message)
{
if (condition)
{
Info(message);
}
}
public static void InfoIf(string category, bool condition, string message)
{
if (condition)
{
Info(category, message);
}
}
public static void Info(string format, params object[] args)
{
Debug.Assert(format != null);
Info(string.Format(CultureInfo.InvariantCulture, format, args));
}
public static void Info(string category, string format, params object[] args)
{
Debug.Assert(format != null);
Info(category, string.Format(CultureInfo.InvariantCulture, format, args));
}
public static void InfoIf(bool condition, string format, params object[] args)
{
if (condition)
{
Info(format, args);
}
}
public static void InfoIf(string category,
bool condition,
string format,
params object[] args)
{
if (condition)
{
Info(category, format, args);
}
}
//
// Verbose level overloads
//
public static void Verbose(string message)
{
try
{
if (s_switch.TraceVerbose)
{
WriteLine(String.Empty, TraceLevel.Verbose, message);
}
}catch{}
}
public static void Verbose(string category, string message)
{
if (GetSwitch(category).TraceVerbose)
{
WriteLine(category, TraceLevel.Verbose, message);
}
}
public static void VerboseIf(bool condition, string message)
{
if (condition)
{
Verbose(message);
}
}
public static void VerboseIf(string category, bool condition, string message)
{
if (condition)
{
Verbose(category, message);
}
}
public static void Verbose(string format, params object[] args)
{
Debug.Assert(format != null);
Verbose(string.Format(CultureInfo.InvariantCulture, format, args));
}
public static void Verbose(string category, string format, params object[] args)
{
Debug.Assert(format != null);
Verbose(category, string.Format(CultureInfo.InvariantCulture, format, args));
}
public static void VerboseIf(bool condition, string format, params object[] args)
{
if (condition)
{
Verbose(format, args);
}
}
public static void VerboseIf(string category,
bool condition,
string format,
params object[] args)
{
if (condition)
{
Verbose(category, format, args);
}
}
//
// Trace Output Format:
// [category:level]PID|ThreadID|08:16:15.134| message.
//
private static void WriteLine(string category,
System.Diagnostics.TraceLevel level,
string message)
{
Debug.Assert(message != null);
string traceLine = string.Format(
CultureInfo.InvariantCulture,
"[{0}:{1}]{2}|{3}|{4:HH}:{4:mm}:{4:ss}.{4:fff}|{5}",
category,
level.ToString(),
Process.GetCurrentProcess().Id,
Thread.CurrentThread.ManagedThreadId,
DateTime.Now,
message);
Trace.WriteLine(traceLine);
}
}
}