C# Winforms: отладка стратегий, чтобы найти причину для System.AccessViolationException
В моем приложении winforms я получаю следующее исключение в случайных случаях:
Application: My.Shell.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
Stack:
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG ByRef)
at System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr, Int32, Int32)
at System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)
at System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)
at System.Windows.Forms.Application.Run(System.Windows.Forms.Form)
at Microsoft.Practices.CompositeUI.WinForms.FormShellApplication`2[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Start()
at Microsoft.Practices.CompositeUI.CabApplication`1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Run()
at My.Shell.ModuleLoader.Main()
Трассировка стека была из окна просмотра событий Windows. (Необработанный обработчик исключений не получил его.)
Я прочитал много статей по этому поводу на SO:
- C# Исключение WinForms: первое случайное исключение типа 'System.AccessViolationException'
- найти причину исключения System.AccessViolationException
- AccessViolationException из System.Windows.Forms, используя WinFormsHost в WPF
- AccessViolationException от комбо: попытка чтения или записи в защищенную память
Оказывается, мое приложение где-то получает доступ к удаленной или поврежденной памяти через собственный метод. Мой вопрос сейчас заключается в том, как найти это место с помощью аварийного дампа, который я сделал с помощью диспетчера задач. Есть ли другие стратегии, чтобы найти причину?
3 ответа
Я обнаружил, что UnhandledException
а также ThreadException
события часто не запускаются в WinForms. В моем приложении у меня есть три разных способа отловить необработанное исключение. Часто это просто try catch
который получает это.
static void Main(string[] args)
{
Application.ThreadException += Application_ThreadException;
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
try
{
var mform = new MainForm();
Application.Run(mform);
}
catch (Exception ex)
{
HandleException(ex);
}
}
private void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
HandleException(e.Exception);
}
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
HandleException(e.ExceptionObject as Exception);
}
private void HandleException(Exception ex)
{
// Do something with it
}
Вероятно, это поможет использовать SOS, разбить первое необработанное исключение и перейти оттуда.
Вы также можете динамически запускать отладчик, если это необходимо. См. "Системная диагностика".
Это позволит вам просмотреть состояние, которое вызвало или разрешило возникновение исключения, а также иметь возможность следовать ему, не дожидаясь появления ошибки, пока подключен отладчик.
Я закончил с этим замечательным инструментом: "Debug Diagnostic Tool" от Microsoft. Смотрите подробности на CodeProject
"Средство диагностики отладки (DebugDiag) предназначено для помощи в устранении проблем, таких как зависания, низкая производительность, утечки памяти или фрагментация, а также сбои в любом процессе пользовательского режима". (microsoft.com) Инструмент DebugDiag гораздо проще в использовании по сравнению с другими инструментами для отладки.
Инструмент автоматически отслеживает конкретный процесс и сохраняет файлы дампа в выбираемую папку. Очень удобно;-)