найти причину исключения System.AccessViolationException - PullRequest
29 голосов
/ 27 февраля 2011

Наше приложение испытывает странное фатальное исключение System.AccessViolationException. Мы видим это, поскольку настроили событие AppDomain.CurrentDomain.UnhandledException для регистрации исключения.

Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.Run(Form mainForm)
   at Bootstrap.Run() in e:\build-dir\src\Bootstrap.cs:line 25

Кажется, что само исключение не содержит больше информации, чем сообщение "Попытка чтения или записи в защищенной памяти. Это часто указывает на то, что другая память повреждена."

  • Какие шаги мы можем предпринять сейчас, чтобы найти причину проблемы?
  • Есть ли способ определить недопустимый адрес или значение указателя, вызвавшее сбой?
  • Можем ли мы узнать, какой нативный код библиотеки вызывал проблему?
  • Есть ли еще возможность отладки / трассировки, которые мы можем включить?

UPDATE

  • Может ли это быть вызвано более ранним не-безопасным использованием WinForms API?

Ответы [ 4 ]

6 голосов
/ 27 февраля 2011

То, что вы испытываете, является точным эквивалентом «Программа столкнулась с проблемой и теперь закрывается», за исключением того, что она перехватывается средой выполнения .NET, а не ОС.

Глядя на трассировку стека, она не запускается вашим кодом, что заставляет меня думать, что она исходит из рабочего потока, созданного используемой вами библиотекой или пользовательским элементом управления.

Единственный способ отследить что-то подобное, это запустить собственные библиотеки под отладчиком, который должен перехватить нарушение прав доступа, прежде чем оно попадет на уровень CLR. Это может быть легко или сложно.

Если нативный код является вашим собственным проектом, то самый простой способ настроить это - поместить проект .NET и проект C ++ в одно и то же решение и убедиться, что проект .NET ссылается на проект C ++. Если вы опубликуете более подробную информацию о вашем окружении, возможно, я смогу дать более конкретный совет.

3 голосов
/ 05 июня 2015

У меня была похожая проблема, и в отличие от @BartRead, постоянно.Для меня некоторый код CLI работал нормально в простом приложении Windows Form, но когда я поместил его в экосистему плагинов larager (многопоточную), сообщения должны были быть обработаны с помощью Application.Run или Application.DoEvents.Если у вас есть доступ к прокачиваемому коду, лучше всего (что сработало для меня) было закомментировать все больше и больше фрагментов кода, сохраняя при этом функциональность.Оказалось, что у меня не было GC :: Alloc'd обратный вызов / делегат, и хотя он был закреплен и все еще на него ссылались, он перемещался в памяти или был помечен для сбора.

если вы используете GC Alloc, обязательно уберите за собой!

3 голосов
/ 20 апреля 2012

Трассировка стека указывает на неверные данные в параметре MSG собственного мессенджера диспетчеризации.Вы пытались загрузить символы из Microsoft и проверить параметры этой трассировки стека.

Не зная элементов управления вашего пользовательского интерфейса и событий, к которым вы подключились, будет трудно определить, в чем именно заключается проблема.

2 голосов
/ 26 июня 2015

У меня была эта проблема при выполнении хранимой процедуры с использованием ADO. эта ошибка имела две причины:

  1. неверная строка подключения.
  2. несоответствие типов параметров (передача long для db-int32 или long в nvarchar (10), что короче)
...