Как отладить нарушение доступа в поле?
Приложение в поле получает это сообщение с перерывами:
![alt text]()
Я не могу воспроизвести это на своей машине. Я также проследил, что я считаю соответствующим кодом и не могу найти доступ к неинициализированным объектам.
Мне никогда не приходилось сталкиваться с такими проблемами.
Я сделал сборку с madExcept и, к сожалению, программа не разбивается, когда она в комплекте.
Любые мнения о madExcept vs. EurekaLog для поиска такого рода вещей? Я никогда не использовал FastMM. Было бы полезно в его ситуации? (Delphi 2010) Любые предложенные флаги для установки в FastMM? Любые другие рекомендации?
Ответы
Ответ 1
Обратите внимание на очень низкий адрес, который вы пытаетесь прочитать. Подобная ошибка почти наверняка означает, что вы попытались разыменовать нулевой указатель, даже если вы не можете найти его.
Учитывая ваше описание поведения, я подозреваю, что у вас происходит топление памяти - что-то взрывает нуль поверх указателя на объект. Когда вы меняете вещи, вы перемещаете вещи, а топа перемещается в безопасное место.
Включите проверку диапазона и проверку переполнения.
Обратите внимание, что объект-нарушитель должен иметь размер не менее 3C0 байт - это должно помочь уменьшить его, большинство объектов будет меньше этого.
То, что я делал в прошлом с такими ошибками, которые отображаются только в поле, помещается в контрольные точки регистрации - кучу строк, которые отображают что-то в некотором роде - простая последовательность чисел в порядке. Узнайте, какое количество показывается, когда он падает, и вы знаете, какие из вас контрольные точки были последними. Если это не сужает его достаточно, вы можете повторить процесс теперь, когда вы его сузили.
Ответ 2
С полным файлом карты вы можете определить точную точку в коде, где это происходит. Надеюсь, у вас есть полный файл карты для этого изображения! Вычитайте $00401000 с адреса, на котором возникает исключение ($ 007ADE8B в вашем случае), и это соответствует значениям в файле карты.
Сделав это, вы знаете, какой объект равен нулю, и оттуда обычно не так сложно выработать то, что происходит.
Один из наиболее распространенных способов для этого - это когда конструктор создает исключение. Когда это происходит, деструктор работает. Если вы получаете доступ в деструкторе, которое не было инициализировано, и делать что-либо, кроме вызова Free на нем, вы получите такое же исключение.
Ответ 3
Похоже, что перезапись памяти, в которой изменение макета памяти (ваша машина против полевого компьютера или добавление madExcept) заставляет переписать что-то безвредное.
FastMM отлично справляется с тем, чтобы подобные проблемы происходили более последовательно (и находили их источник). Загрузите полную версию FastMM, добавьте ее в качестве первого блока вашего проекта и включите FullDebugMode в его настройках.
Это может привести к тому, что проблема будет немедленно воспроизведена на вашем компьютере. Если нет, не забудьте развернуть FastMM_FullDebugMode.dll с вашим приложением для тестирования. Храните файл madExcept и вставьте файл .map для стеков вызовов.