Недавно я исправил дефект в нашем продукте, симптомом которого было нарушение прав доступа, вызванное обращением к оборванному указателю.
Для хорошей практики я добавил модульный тест, чтобы убедиться, что ошибка не вернется. При написании модульного теста я всегда отказываюсь от исправления дефекта и гарантирую, что модульный тест не работает, иначе я знаю, что он не выполняет свою работу должным образом.
После отказа от исправления дефекта я обнаружил, что мой модульный тест все еще проходит (не очень хорошо). Когда я прикрепил отладчик к модульному тесту, чтобы увидеть, почему он проходит, тест провалился (т. е. было выдано исключение), и я мог сломаться и увидеть, что стек вызовов совпадает со стеком исходного дефекта, который я исправил.
Я не менял настройки «Разрыв при исключении» в Visual Studio 2005, и это действительно критическое исключение Win32, которое приводит к завершению работы тестовой системы (т. е. изящного обработчика исключений нет).
Текст исключения:
Unhandled exception at 0x0040fc59 in _testcase.exe: 0xC0000005:
Access violation reading location 0xcdcdcdcd.
Примечание. Местоположение не всегда 0xcdcdcdcd
(выделенная, но незаписанная память кучи Win32). Иногда это 0x00000000
, а иногда другой адрес.
Это похоже на обратную сторону традиционного Heisenbug, когда проблема исчезает при наблюдении за ней через отладчик. В моем случае наблюдение за ним через отладчик приводит к появлению проблемы!
Моя первоначальная мысль заключалась в том, что это состояние гонки, выявляемое разницей во времени в отладчике. Однако, когда я добавил трассировку в код и запустил его отдельно от отладчика, данные, которые я распечатывал, указывали мне, что приложение должно быть прервано так же, как при работе под отладчиком. Но это не так!
Любые предложения относительно того, что может быть причиной этого?
Обновление: я выясняю причину этой проблемы. См. manager">этот вопрос для более подробной информации. Обновлю этот вопрос ответом, если найду его.
sem_wait
; отладчик прервал поток при его присоединении, в результате чегоsem_wait
вернулся с ошибкойEINTR
. Затем поток продолжил выполнение, и случилось что-то плохое. Достаточно сказать, что я узнал, почему важно проверять коды ошибок... - person James McNellis   schedule 25.11.2010