Каковы некоторые методы устранения периодически возникающих нарушений прав доступа на устройстве Windows Mobile?

StackOverflow https://stackoverflow.com/questions/402957

Вопрос

У меня есть большое приложение Compact Frameworks V2.0, которое в большинстве случаев работает очень хорошо.На некоторых устройствах примерно раз в день пользователь получает собственную ошибку 0xC0000005, которая не перехватывается стандартным управляемым блоком Try/Catch.

Мое приложение синхронизируется с сервером посредством вызовов ASMX через фиксированные промежутки времени.Проблема возникает во время синхронизации.Помимо вызова ASMX, который происходит во время синхронизации, существует значительная бизнес-логика, но 98% ее составляет управляемый код.Я просмотрел все свои P/Invokes и собственные библиотеки C++ приложений и на данный момент я примерно на 95% уверен, что проблема не в этом.

Поскольку это происходит только на определенных устройствах и очень редко (реже одного раза в день), изолировать очень сложно.Я внедрил свой код, и кажется, что это происходит в случайных местах приложения, поэтому я подозреваю, что что-то повреждает память.

Любые мысли о том, как устранить эту неполадку в дальнейшем, будут оценены по достоинству.

Это было полезно?

Решение 2

Моя собственная обработка исключений C++ не включала асинхронные исключения и, следовательно, не перехватывала исключения нарушения прав доступа.

Это может/не может быть полезно для моей проблемы, но может быть полезно для других.

Использование переключателя /EHa, как описано в этой ссылке, позволит перехватывать следующие типы исключений:

http://msdn.microsoft.com/en-us/library/1deeycx5.aspx

Другие советы

Ошибка 0xC0000005 — это нарушение прав доступа, поэтому что-то пытается прочитать или записать на адрес, к которому у него нет прав доступа.Их, как правило, очень сложно найти, и опыт является одним из лучших инструментов (ну, отладчик Platform Builder тоже очень полезен, но это совершенно отдельный путь отладки и требует опыта, которого у вас, вероятно, нет или который у вас уже был бы). попробовал).Я считаю, что ведение журналов, как правило, менее полезно, чем субтрактивное кодирование — удаление вызовов P/invoke с помощью фиктивных управляемых вызовов, когда это возможно.

Нарушения доступа в управляемых приложениях обычно происходят по одной из следующих причин:

  • Вы P/вызываете собственный API, передавая дескриптор управляемого объекта, и собственный API использует этот дескриптор.Если вы получаете сбор и сжатие во время работы собственного API, управляемый объект может переместиться, и указатель станет недействительным.
  • Вы выполняете P/вызов чего-то с буфером, который слишком мал или меньше размера, который вы передаете, и API переполняет операции чтения или записи.
  • Указатель (IntPtr и т. д.), который вы передаете вызову P/Invoke, недействителен (-1 или 0), и встроенный код не проверяет его перед использованием.
  • Вы выполняете P/вызов собственного вызова, а собственному коду не хватает памяти (обычно виртуальной), и он не проверяет наличие неудачных выделений и не читает/записывает по недопустимому адресу.
  • Вы используете GCHandle, который не инициализирован или каким-то образом указывает на уже завершенный и собранный объект (поэтому он не указывает на объект, он указывает на адрес, где раньше находился объект).
  • Ваше приложение использует дескриптор чего-то, что стало недействительным из-за сна/пробуждения.Это более эзотерично, но, безусловно, случается.Например, если вы запускаете приложение с карты памяти, все приложение не загружается в ОЗУ.Используемые детали передаются по запросу для исполнения.Это все хорошо.Теперь, если вы выключите устройство, все драйверы отключатся.При резервном включении многие устройства просто повторно подключают устройства хранения.Когда вашему приложению требуется дополнительная страница в программе, оно уже не там, где было, и умирает.Аналогичное поведение может произойти с базами данных в смонтированных хранилищах.Если у вас есть открытый дескриптор базы данных, после цикла сна/пробуждения дескриптор соединения может стать недействительным.

Здесь вы заметите тенденцию, заключающуюся в том, что почти все это P/Invoke, и это не случайно.Довольно сложно заставить управляемый код делать это самостоятельно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top