Какие существуют методы для устранения неполадок, связанных с прерывистым нарушением прав доступа на устройстве Windows Mobile?
У меня есть большое приложение Compact Frameworks V2.0, которое в большинстве случаев работает очень хорошо. На некоторых устройствах примерно раз в день пользователь получает собственную ошибку 0xC0000005, которая не перехватывается стандартным управляемым блоком Try/Catch.
Мое приложение синхронизируется с сервером через вызовы ASMX через фиксированные интервалы. Проблема возникает во время синхронизации. В дополнение к вызову ASMX, который происходит во время синхронизации, существует значительная бизнес-логика, но 98% этого объема - управляемый код. Я просмотрел все свои P/Invokes и нативные библиотеки C++ приложений, и на данный момент я на 95% уверен, что проблема не в этом.
Поскольку это происходит только на определенных устройствах и очень редко (реже одного раза в день), его очень трудно изолировать. Я описал свой код, и он выглядит так, как будто это происходит в разных местах приложения, поэтому я подозреваю, что что-то портит память.
Любые мысли о том, как устранить эту проблему, будут оценены.
2 ответа
Моя собственная обработка исключений C++ не включала асинхронное исключение и, следовательно, не перехватывала исключения нарушения доступа.
Это может / не может быть полезно для моей проблемы, но может быть полезно для других.
Использование параметра /EHa, как описано в этой ссылке, позволит перехватывать исключения следующих типов:
0xC0000005 является нарушением доступа, поэтому что-то пытается прочитать или записать адрес, к которому у него нет прав доступа. Их, как правило, очень сложно найти, и опыт работы - один из лучших инструментов (ну, отладчик Platform Builder тоже очень полезен, но это отдельная возможность отладки, требующая опыта, которого вы, вероятно, не имеете или уже имели бы). попробовал это). Я считаю, что ведение журнала имеет тенденцию быть менее полезным, чем вычитающее кодирование - удаление вызовов P/invoke с помощью фиктивных управляемых вызовов, когда это возможно.
Нарушения доступа в управляемых приложениях обычно происходят по одной из следующих причин:
- Вы выполняете P/Invoke собственного API, передавая дескриптор управляемому объекту, и собственный API использует этот дескриптор. Если вы получите коллекцию и сжатие во время работы нативного API, управляемый объект может переместиться, и указатель станет недействительным.
- Вы P/Invoke что-то с буфером, который слишком мал или меньше, чем размер, который вы передаете, и API переполняет чтение или запись
- Указатель (IntPtr и т. Д.), Который вы передаете вызову P/Invoke, недопустим (-1 или 0), и нативный не проверяет его перед использованием
- Вы выполняете вызов P/Invoke для собственного вызова, а собственный код исчерпывает память (обычно виртуальную) и не проверяет наличие неудачных распределений и читает / записывает на неверный адрес
- Вы используете GCHandle, который не инициализирован или который каким-то образом указывает на уже завершенный и собранный объект (поэтому он не указывает на объект, он указывает на адрес, где раньше был объект)
- Ваше приложение использует дескриптор чего-то, что стало недействительным в результате сна / пробуждения. Это более эзотерично, но, безусловно, бывает. Например, если вы запускаете приложение с карты памяти, все приложение не загружается в оперативную память. Части в использовании выровнены по требованию для выполнения. Это все хорошо. Теперь, если вы выключите устройство, все драйверы отключатся. Когда вы включаете питание, многие устройства просто перемонтируют устройства хранения. Когда вашему приложению нужно запросить страницу в большем количестве программ, оно больше не там, где оно было, и оно умирает. Подобное поведение может происходить с базами данных в подключенных хранилищах. Если у вас есть открытый дескриптор базы данных, после цикла ожидания / сна дескриптор соединения может перестать быть действительным.
Здесь вы заметите тенденцию, что почти все они являются P/Invoke s, и это не случайно. Довольно сложно получить управляемый код, чтобы сделать это самостоятельно.