Введение
Баг программного обеспечения, который, кажется, меняется при отладке, – это так называемый Heisenbug в дистрибутиве Linux.
the Linux distribution codenamed Heisenbug
В компьютерном программировании, Heisenbug – это программный баг, который, кажется, исчезает или изменяет своё поведение при попытке его изучения. Этот термин является игрой слов, основанной на имени Вернера Гейзенберга, физика, впервые сформулировавшего принцип неопределённости квантовой механики, согласно которому сам акт наблюдения за системой неизбежно изменяет её состояние. В электронике аналогичный эффект известен как эффект щупа, когда подключение тестового щупа к устройству меняет его поведение. Иногда, в шутку, для обозначения других необычных программных ошибок предлагаются подобные термины, такие как bohrbug, mandelbug, hindenbug и schrödinbug (см. раздел «Связанные термины»).
Примеры
Хайзенбуги возникают из-за того, что обычные попытки отладки программы, такие как вставка операторов вывода или запуск программы с отладчиком, как правило, приводят к изменению её поведения незаметными способами, например, к изменению адресов переменных в памяти или времени выполнения. Распространенным примером хайзенбуга является ошибка, которая проявляется при компиляции программы с оптимизирующим компилятором, но исчезает при компиляции той же программы без оптимизации (что часто делается для анализа с помощью отладчика). Во время отладки значения, которые оптимизированная программа обычно хранит в регистрах, часто перемещаются в основную память. Это может повлиять, например, на результат сравнения чисел с плавающей точкой, поскольку значение в памяти может иметь меньший диапазон и точность, чем значение в регистре. Аналогично, хайзенбуги могут быть вызваны побочными эффектами в тестовых выражениях, используемых в runtime assertions в языках C и C++, где тестовое выражение не вычисляется при отключенных assertions в производственном коде с помощью макроса NDEBUG. Другими распространенными причинами хайзенбугов являются использование значения неинициализированной переменной (которая может изменить свой адрес или начальное значение во время отладки) или обращение к недействительному указателю (который может указывать на другое место при отладке). Отладчики также часто позволяют использовать точки останова или предоставляют другие пользовательские интерфейсы, которые приводят к скрытому выполнению дополнительного исходного кода (например, аксессоров свойств), что, в свою очередь, может изменить состояние программы. Конечные пользователи могут столкнуться с хайзенбугом, когда сам процесс создания скриншота для наблюдения за ошибкой устраняет её, а на скриншоте отображается полностью рабочее состояние. Этот эффект может возникать при взаимодействии сложных программных стеков, например, когда веб-браузер использует аппаратное ускорение графической карты, вызывающее ошибки рендеринга на физическом экране, которые не видны на скриншоте. Время также может играть роль в хайзенбугах, особенно в многопоточных приложениях. Запуск программы под управлением отладчика может изменить время выполнения программы по сравнению с нормальным выполнением. Чувствительные ко времени ошибки, такие как гонки данных, могут не возникать, когда программа замедляется пошаговым выполнением строк кода в отладчике. Это особенно верно, когда поведение включает взаимодействие с сущностью, не находящейся под контролем отладчика, например, при отладке обработки сетевых пакетов между двумя машинами, когда под контролем отладчика находится только одна из них. Хайзенбуги можно рассматривать как проявление эффекта наблюдателя в информационных технологиях. Разочарованные программисты могут в шутку винить в хайзенбуге фазу луны или (если это произошло только один раз) объяснять это случайной ошибкой, вызванной альфа-частицами или космическими лучами, воздействующими на оборудование – хорошо задокументированным явлением, известным как эффекты одиночных событий.
Связанные термины
В отличие от них, боргбаг – это "хороший, надежный баг". Как и детерминированная модель атома Бора, они не меняют своего поведения и относительно легко обнаруживаются. Мандельбаг (названный в честь фрактала Бенуа Мандельброта) – это баг, причины которого настолько сложны, что его невозможно исправить, или его поведение кажется хаотичным и даже недетерминированным. (Названный в честь катастрофы "Гинденбург") – это баг с катастрофическими последствиями. Хиггс-багсон (названный в честь частицы бозона Хиггса) – это баг, существование которого предсказывается на основе других наблюдаемых условий (чаще всего, расплывчатых записей в логах и непроверенных сообщений пользователей), но его трудно, если не невозможно, искусственно воспроизвести в среде разработки или тестирования. Этот термин также может относиться к багу, который очевиден в коде (математически доказан), но не проявляется при выполнении (при этом его трудно или невозможно обнаружить на практике).
Этимология
Термин был использован в 1985 году Джимом Грей в статье о сбоях в работе программного обеспечения (и иногда ошибочно приписывается ему из-за этой публикации), а также в 1986 году Джонатаном Кларком и Жахаем Стюартом в списке рассылки (впоследствии группе новостей Usenet) comp.risks. Брюс Линдсей, исследователь IBM, подтвердил в интервью для ACM Queue в 2004 году, что он присутствовал при первоначальном определении Heisenbug. Более раннее упоминание в публикациях ACM относится к 1983 году.
Резолюция
Гейзенбаги сложно идентифицировать и исправить; часто попытки их устранения приводят к ещё более неожиданному поведению. Поскольку проблема возникает как следствие отдельной, базовой ошибки, поведение может быть трудно предсказать и проанализировать в процессе отладки. В целом, количество обнаруженных гейзенбагов должно уменьшаться по мере развития программного обеспечения.