Uncatchable AccesViolationException - PullRequest
       11

Uncatchable AccesViolationException

2 голосов
/ 28 апреля 2010

Я почти впал в отчаяние ... Я разрабатываю приложение полевого сервиса для Windows Mobile 6.1, используя C # и довольно много p / Invoking. (Я думаю, что я ссылаюсь на около 50 нативных функций)

При нормальных обстоятельствах это проходит без каких-либо проблем, но когда я начинаю подчеркивать ГХ, я получаю неприятную ошибку 0xC0000005, которая кажется неуловимой. В моем тесте я быстро закрываю и открываю диалоговую форму (форма использовала нативные функции, но для тестирования я закомментировал их), и через некоторое время появляется сообщение об ошибке Windows Mobile, чтобы сообщить мне, что произошла фатальная ошибка. ошибка в моем приложении.

Мой код использует try-catch вокруг Application.Run(masterForm); и подключается к событию CurrentDomain.UnhandledException, но приложение по-прежнему падает. Даже когда я присоединяю отладчик, Visual Studio просто сообщает мне «Удаленное соединение с устройством было потеряно», когда возникает исключение ..

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

Поток, в котором происходит приложение, мне неизвестен, модуль, в котором возникает ошибка, время от времени отличается (я видел мои application.exe, WS2.dll, netcfagl3_5.dll и mscoree3_5.dll), даже код ошибки не всегда одинаков. (в большинстве случаев это 0xC0000005, но я также видел ошибку 0X80000002, которая является предупреждением, учитывающим первый байт?)

Я попытался отладить через bugtrap, но, как ни странно, это вылетает с тем же кодом ошибки (0xC0000005). Я пытался открыть файл kdmp с помощью Visual Studio, но, похоже, я не вижу в этом никакого смысла, потому что он показывает мне код дизассемблера только при появлении ошибки (если только у меня нет нужных файлов .pbb, которые мне не нужны «т). То же самое касается WinDbg.

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

Любая помощь очень ценится!

[ПРАВИТЬ 3 мая 2010 г.]

Как вы можете видеть в моем комментарии к Гансу, я перепроверил всю программу после того, как я раскомментировал все P / Invokes, но это не решило мою проблему. Я попытался воспроизвести ошибку, используя как можно меньше кода, и в конечном итоге похоже, что многопоточный доступ дает мне все проблемы.

В моем приложении у меня есть пользовательский контроль, который функционирует как список прокрутки пальцем / щелчком. В этом элементе управления я использую растровое изображение для каждого элемента в списке как холст. Рисование на этом холсте обрабатывается отдельным потоком, и когда я отключаю этот поток, ошибка, похоже, исчезает ... Я проведу еще несколько тестов и опубликую результаты здесь.

Ответы [ 2 ]

4 голосов
/ 28 апреля 2010

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

Двумя наиболее распространенными причинами AV являются

  • Повреждение кучи. Неуправляемый код неправильно записал данные в кучу, разрушив структурную целостность кучи. Обычно вызывается переполнением границы выделенного блока памяти. Или используя блок кучи после его освобождения. Очень трудно диагностировать, исключение будет возбуждено еще долго после нанесения ущерба.

  • Повреждение стека. Чаще всего это вызвано переполнением границ массива, выделенного в стеке. Это может перезаписать значения других переменных в стеке или уничтожить адрес возврата функции. Немного легче диагностировать, он хорошо повторяется и дает немедленный эффект. Одним из побочных эффектов является то, что отладчик теряет способность отображать стек вызовов сразу после нанесения ущерба.

Повреждение кучи является вероятным и сложным. Обычно это решается путем отладки кода в отладочной сборке с помощью распределителя отладки, который следит за целостностью кучи. Заголовок <crtdbg.h> обеспечивает один. Это не гарантированный подход, у вас могут быть некоторые действительно неприятные гейзенги, которые только поднимают голову в сборке Release. Тогда доступно очень мало вариантов, кроме тщательного анализа кода. Удачи, тебе это понадобится.

0 голосов
/ 25 мая 2010

Оказывается, исключение вызвано блокировкой.

В моем коде есть целое число _drawThreadIsRunning, которое установлено в 1, когда работает поток вывода, и установлено в 0 в противном случае. Я установил это значение, используя Interlocked:

if (Interlocked.Exchange(ref _drawThreadIsRunning, 1) == 0) { /* run thread */ }

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

Спасибо за помощь, ребята!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...