2009-06-10 3 views
1

Мое приложение аварийно завершает работу около 18 часов. Я не могу отлаживать точку в коде, где он фактически сбой. Я проверил стек вызовов - он не предоставляет никакой информации как таковой. Последние несколько вызовов в стеке вызовов выделены серым цветом, что означает, что я не вижу код этой части - все они принадлежат библиотекам MFC.Сбой при сбоях говорит: Адрес для обнаружения нарушения доступа

Однако, я получаю это 'Microsoft Visual Studio' всплывающий, когда он выходит из строя, который говорит:

Необработанного исключения в 0x7c809e8a в NIMCAsst.exe: 0xC0000005: Нарушения прав доступа для чтения расположения 0x154c6000.

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

+0

Почему именно вы не можете отлаживать? – sharptooth

+1

Он просто сбой в какой-то случайной точке. Он входит в DLL MFC и падает там, и стек вызовов не говорит, какая точка в моем коде взяла контроль там. –

+0

Если у вас есть отладчик, вы должны четко видеть, какая строка кода вы вызываете в MFC. Если это не включено, или вы имеете файлы .pdb, не синхронные с исполняемым файлом. – sharptooth

ответ

5

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

2

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

Моей первой предположения было бы изучить код, вызывающий код, который разбился на возможные проблемы, которые могли вызвать его. Получаете ли вы какие-либо другие исключения или ошибки перед сбоем? Может быть, вы игнорируете возврат ошибки? Вы пытались использовать Debug Heap? Как насчет adplus? Application verifier, чтобы включить проверки кучи?

Другие возможности включают запуск такого инструмента, как pclint над кодом, для проверки очевидных проблем использования памяти. Вы используете потоки? Возможно, есть состояние гонки. Список может продолжаться вечно.

+0

Ошибка может произойти, но когда произойдет сбой, это не будет последовательным - он сработает в любое время после работы в течение 6 часов. Поэтому я не могу поместить часы на ошибки, возвращенные в течение столь длительного времени. –

+0

Да, это многопоточное приложение. –

1

В приведенной выше информации указывается, какая память была обращена нелегально.

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

Вы говорите, что видите стек вызовов, который предполагает, что вы используете отладчик. Исходный код MFC доступен (но, возможно, не со всеми версиями vC++), поэтому в принципе можно проследить его. Какую версию VC++ вы используете?

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

Иногда «местоположение» может быть распознано как данные, и в этом случае у вас есть подсказка. F.E. если ошибка сказала:

Доступ место чтения нарушения 0x31323334

вы бы признать это как часть ASCII строки «1234», и это может привести вас к преступнику.

+0

Я использую Visual Studio 2005, и я приложил приложение к решению для отладки. –

1

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

+0

Не только код пользователя может давать некорректно структурированные данные, но он может, например, вызвать функцию, вызывающую обратный вызов при завершении, и дать ему указатель userdata на действительный объект, но объект удаляется в момент поступления обратного вызова. Возможности здесь бесконечны. – sharptooth

1

Является ли крах четко воспроизводимым?

Если да, используйте Logfiles! Вы должны использовать файл журнала и добавлять операторы чисел, которые просто регистрируют переданный исходный файл/номер строки. Начните с нескольких операторов в точке входа (обработчик основного события) и наиболее распространенных путей выполнения. После сбоя проверьте последнюю запись в файле журнала. Затем добавьте новые записи по пути/пути, которые должны были быть переданы и т. Д. Обычно после нескольких итераций этой работы вы найдете точку отказа. В случае вашего долгого времени ожидания файл журнала может стать огромным, и каждая итерация займет еще 18 часов. Возможно, вам придется добавить некоторую технику вращения файлов журналов и т. Д. Но с помощью этой техники я смог найти некоторые сопоставимые ошибки.

несколько вопросов:

многопоточной ли ваше приложение?

Использует ли он какие-либо массивы, не управляемые stl или сопоставимыми контейнерами (использует ли C-Strings, C/C++ - массивы и т. Д.)?

+0

Да, приложение многопоточное. Нет массивов, которые не управляются stl. Ведение журнала - хорошая идея. –

+0

Также, добавляя к файлу журнала, я рекомендовал бы каждый раз открывать, писать, промывать и закрывать файл журнала, чтобы при сбое лог-файл был правильно закрыт последним напечатанным текстом. – KPexEA

0

Попробуйте подключить отладчик к процессу и отлаживать отладчик при нарушениях доступа.

Если это невозможно, мы используем инструмент, называемый «самозагрузчик процесса пользователя», чтобы создать дамп памяти процесса в точке, где произошло нарушение прав доступа. Вы можете найти это скачать здесь:

http://www.microsoft.com/downloads/details.aspx?FamilyID=E089CA41-6A87-40C8-BF69-28AC08570B7E&displaylang=en

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

Обратите внимание, что все нарушения доступа в вашем процессе захватываются - даже те, которые затем обрабатываются, также полный дамп может создавать время для создания в зависимости от объема памяти, используемой приложением (10-20 секунд для процесс потребления 100-200 МБ частной памяти). По этой причине, вероятно, не рекомендуется включать ее в общесистемную.

Вы должны затем проанализировать дамп с помощью таких инструментов, как WinDbg (http://www.microsoft.com/whdc/devtools/debugging/default.mspx), чтобы выяснить, что произошло - в большинстве случаев вы обнаружите, что вам нужен только мини-накопитель, а не полный дамп (однако, если ваше приложение не использует много памяти, тогда существует множество недостатков наличия полного дампа, отличного от размера дампа, и времени, необходимого для создания дампа).

И, наконец, следует предупредить, что отладочные нарушения доступа с использованием WinDbg могут быть довольно сложным и сложным процессом - если вы можете получить трассировку стека другим способом, тогда вы можете попробовать это первым.

0

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

Смежные вопросы