Я сталкиваюсь с необычным сбоем в нашем программном обеспечении, и у меня много проблем, отлаживая его, и поэтому я ищу SO советы о том, как справиться с этим.
Сбой - это нарушение доступа, считывающее указатель NULL:
Первое случайное исключение в $00CF0041. Класс исключения $C0000005 с сообщением "Нарушение доступа при 0x00cf0041: читать адреса 0x00000000 '.
Это случается только "иногда" - мне не удалось выяснить какую-либо рифму или причину, но, когда - и только в основном потоке. Когда это происходит, стек вызовов содержит одну неверную запись:
Для основного потока, который это значит, он должен показать большой стек, полный других элементов.
В этот момент все остальные потоки неактивны (в основном сидят в WaitForSingleObject
или аналогичной функции.) Я только видел, что этот сбой произошел в основном потоке. Он всегда имеет один и тот же стек вызовов одной записи, в том же методе по тому же адресу. Этот метод может быть или не быть связан - мы используем VCL в нашем приложении. Моя ставка, однако, заключается в том, что что-то (возможно, совсем недавно) разрушает стек, а адрес, где он сбой, является случайным. Обратите внимание, что это был один и тот же адрес в нескольких сборках, но, вероятно, он не был случайным.
Вот что я пробовал:
- Попытка воспроизвести его надежно в определенный момент. Я не нашел ничего, что воспроизводит его каждый раз, и несколько вещей, которые иногда случаются или нет, без видимых причин. Это не "узкие" действия, чтобы сузить его до определенного раздела кода. Это может быть связано с синхронизацией, но в момент, когда IDE ломается, другие потоки обычно ничего не делают. Я не могу исключить проблему с потоками, но думаю, что это маловероятно.
- Создание дополнительных инструкций отладки (дополнительная информация об отладке, дополнительные подтверждения и т.д.) После этого авария никогда не возникает.
- Работает с Codeguard. После этого авария никогда не возникает, и Codeguard не показывает ошибок.
Мои вопросы:
1. Как узнать, какой код вызвал сбой? Как сделать эквивалент ходьбы по стопке?
2. Какой общий совет у вас есть, чтобы проследить причину этого сбоя?
Я использую Embarcadero RAD Studio 2010 (проект в основном содержит код С++ Builder и небольшие количества Delphi.)
Изменить: Я думал, что должен добавить то, что на самом деле вызвало это. Был поток, который назывался ReadDirectoryChangesW
, а затем, используя GetOverlappedResult
, ждал продолжения события и сделал что-то с изменениями. Событие также было сигнализировано, чтобы завершить поток после установки флага состояния. Проблема заключалась в том, что когда поток вышел из него, он никогда не назывался CancelIO
. В результате Windows по-прежнему отслеживала изменения и, вероятно, все еще записывала в буфер при изменении каталога, даже несмотря на то, что структура перекрытия и перекрытие буфера перестали существовать (а также контекст потока, в котором они были созданы.) Когда CancelIO
был вызван, больше не было сбоев.