Стратегии поиска гейзенбагов - PullRequest
7 голосов
/ 01 ноября 2010

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

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

В целом это очень расстраивает.Каковы ваши стратегии и опыт работы с такими ошибками?

Редактировать: Я использую Visual C ++ 2005, но я думаю, что этот вопрос касается многих (всех) языков и сред разработки.

Ответы [ 3 ]

4 голосов
/ 01 ноября 2010

Если вы можете определить точку (точки), в которой проблема впервые видна (очевидно, не тогда, когда это вызвано), создайте там исключение и используйте Process Dumper , чтобыполучить дамп для посмертной отладки.

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

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

Параметры проверки - сборка с /W4 только для того, чтобы убедиться, что ничего очевидного не было пропущено.Проверьте код и предупреждения для приведений в стиле C или reinterpret_cast на случай, если кто-то выбросил чудесное, но важное предупреждение или сообщение об ошибке.

2 голосов
/ 01 ноября 2010

Я обнаружил, что запуск lint поверх моего кода C / C ++ / Java и проверка всех предупреждений, которые он предлагает, привели к тому, что эти условия гонки просто исчезли. Но это не решение. Никогда не кодируйте случайно. Вы должны понимать, что вы исправили и почему это решило проблему.

Я полагаю, что именно K (&& ||) R заявил, что обширные сообщения журналирования сделали больше, чтобы помочь им отладить код, чем любой отладчик - особенно в многопоточных средах, но цитирование необходимо.

Тщательный просмотр очень подробного следа всей деятельности, которая привела к возникновению ошибки, действительно очень помогает.

1 голос
/ 01 ноября 2010

Когда все методы закончены и BoundsCheckers или RationalPurify не помогают.Я обычно использую очень тупую технику.Мы обнаружили это на первом курсе университета.По русски это называется очень грубо.

Итак, я начинаю с выбора подозрительного блока / модуля, который не работает в многопоточной среде.Если это невозможно, то структура программы перефакторируется.

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

Если нет, то же метод применяется для обнаружения предусловия ошибки, поэтому я комментирую код, который предшествует блоку преступника.

...