- PVSM.RU - https://www.pvsm.ru -
[1]
/ фото Lars Zimmermann [2] CC BY
Heisenbug [3] (гейзенбаг или хайзенбаг) — термин, описывающий ошибки, которые меняют свойства во время отладки кода. То есть они исчезают при тестировании и дебаггинге, но проявляются в продакшене.
Название «гейзенбаг» отсылает к принципу неопределенности Гейзенберга [4] из квантовой механики. В общих чертах его можно описать как неожиданное изменение свойств наблюдаемого объекта в результате факта наблюдения.
Автором термина «гейзенбаг» считается сотрудник исследовательского центра IBM Брюс Линдсей (Bruce Lindsay). Он внес вклад в развитие реляционных баз данных и занимался разработкой корпоративной СУБД IBM System R [5].
В 1985 году во время учебы в университете Беркли Брюс и Джим Грей [6] (James Nicholas Gray), американский ученый в области теории вычислительных систем, трудились [7] над ОС CAL-TSS. Она писалась специально для двухпроцессорного мейнфрейма Control Data 6400 [8] [PDF [9], стр.3], на котором военные обрабатывали большие объемы данных.
Само собой, в процессе разработки возникали баги. Но несколько из них были особенными — как только инженеры пытались их исправить, они исчезали. В то время Линдсей как раз изучал физику и принцип Гейзенберга в частности. Внезапно Линдсея осенило — они с Греем стали свидетелями аналогичного явления: ошибки исчезали, потому что наблюдение влияло на свойства объекта. Отсюда и пошло название «гейзенбаг».
Эту истории Линдсей рассказал в интервью [7] с представителями Ассоциации вычислительной техники [10] (ACM) в 2003 году.
Пользователи в сети и на тематических платформах вроде Stack Overflow поделились несколькими примерами гейзенбагов, с которыми они встречались в своих проектах. Один из резидентов SO пытался вычислить площадь фигуры между двумя кривыми с точностью до трех знаков после запятой. Для отладки алгоритма на C++ он добавил строку:
cout << current << endl;
Но как только он её закомментировал, код перестал работать и зациклился. Программа выглядела следующим образом [11]:
#include <iostream>
#include <cmath>
using namespace std;
double up = 19.0 + (61.0/125.0);
double down = -32.0 - (2.0/3.0);
double rectangle = (up - down) * 8.0;
double f(double x) {
return (pow(x, 4.0)/500.0) - (pow(x, 2.0)/200.0) - 0.012;
}
double g(double x) {
return -(pow(x, 3.0)/30.0) + (x/20.0) + (1.0/6.0);
}
double area_upper(double x, double step) {
return (((up - f(x)) + (up - f(x + step))) * step) / 2.0;
}
double area_lower(double x, double step) {
return (((g(x) - down) + (g(x + step) - down)) * step) / 2.0;
}
double area(double x, double step) {
return area_upper(x, step) + area_lower(x, step);
}
int main() {
double current = 0, last = 0, step = 1.0;
do {
last = current;
step /= 10.0;
current = 0;
for(double x = 2.0; x < 10.0; x += step) current += area(x, step);
current = rectangle - current;
current = round(current * 1000.0) / 1000.0;
//cout << current << endl; //<-- COMMENT BACK IN TO "FIX" BUG
} while(current != last);
cout << current << endl;
return 0;
}
Суть гейзенбага [12]: когда нет printout, программа выполняет сравнение с высокой точностью в регистрах процессора. При этом точность результата превышает возможности double. Для вывода значения компилятор возвращает результат вычислений в основную память — при этом дробная часть отбрасывается. И последующее сравнение в while приводит к верному результату. Когда строчка закомментирована, неявного усечения дробной части не происходит. По этой причине два значения в while всегда оказываются неравными друг другу. В качестве решения проблемы один из участников обсуждения предложил использовать приближенное сравнение чисел с плавающей запятой.
Еще одной историей про гейзенбаг поделились инженеры [13], работавшие со средой языка Smalltalk-80 [14] на Unix. Они заметили, что система зависала, если оставить её на какое-то время без дела. Но после перемещения курсора мыши, все вновь работало как обычно.
Проблема была связана с планировщиком Unix, который снижал приоритет задач, которые простаивают. В какой-то момент приоритет понижался настолько, что процессы в Smalltalk не успевали завершаться. Стек задач разрастался и «вешал» программу. Когда пользователь двигал курсор, ОС восстанавливала приоритет и все возвращалось на круги своя.
Есть еще ряд терминов, которые описывают разного рода ошибки: Борбаг, Мандельбаг, Шрёдинбаг.
Борбаг [15] — противоположность гейзенбага — обычная ошибка, которую легко найти и исправить. Названа в честь Нильса Бора, который в 1913 году предложил простую и понятную модель строения атома. Согласно этой модели, электроны атома двигаются по определенным орбитам, значит, их импульс и радиус движения можно предсказывать. Аналогично, появление борбагов можно предсказывать, если создать для них нужные условия.

/ фото OLCF at ORNL [16] CC BY
Шрёдинбаг [17] — ошибка, которая существует и не существует одновременно, пока на нее не посмотрит разработчик. Название ошибка получила в честь известного мысленного эксперимента [18].
Что касается мандельбага [19], то это ошибка, из-за которой система ведет себя хаотично и непредсказуемо. Феномен назван в честь физика, математика и создателя фрактальной геометрии Бенуа Мандельброта [20].
Примеров гейзенбагов (и других *багов) — множество [13]. Их очень сложно искать, но причины возникновения обычно банальны: неинициализированная переменная, ошибки синхронизации в многопоточной среде или проблемы с алгоритмами удаления «мёртвого» кода [21]. Получается, что для борьбы с подобными ошибками их нужно отсекать еще на этапе проектирования приложения.
Автор: ИТ-ГРАДовец
Источник [27]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/blog-kompanii-it-grad/314445
Ссылки в тексте:
[1] Image: https://habr.com/ru/company/it-grad/blog/448002/
[2] Lars Zimmermann: https://www.flickr.com/photos/larszi/34535448502
[3] Heisenbug: http://wiki.c2.com/?HeisenBug
[4] принципу неопределенности Гейзенберга: https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D0%BD%D0%B5%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D1%91%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D0%B8
[5] IBM System R: https://ru.wikipedia.org/wiki/IBM_System_R
[6] Джим Грей: https://ru.wikipedia.org/wiki/%D0%93%D1%80%D0%B5%D0%B9,_%D0%94%D0%B6%D0%B8%D0%BC
[7] трудились: http://www.walterchang.info/SIGMOD-BLindsay-p71-winslett.pdf
[8] Control Data 6400: https://ru.wikipedia.org/wiki/CDC_6400
[9] PDF: https://www.microsoft.com/en-us/research/wp-content/uploads/2016/11/07-ReliableOS.pdf
[10] Ассоциации вычислительной техники: https://ru.wikipedia.org/wiki/%D0%90%D1%81%D1%81%D0%BE%D1%86%D0%B8%D0%B0%D1%86%D0%B8%D1%8F_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D1%82%D0%B5%D1%85%D0%BD%D0%B8%D0%BA%D0%B8
[11] выглядела следующим образом: https://stackoverflow.com/questions/28722647/infinite-loop-heisenbug-it-exits-if-i-add-a-printout
[12] Суть гейзенбага: https://stackoverflow.com/questions/29297896/clarification-of-what-a-heisenbug-is
[13] поделились инженеры: http://wiki.c2.com/?HeisenBugExamples
[14] Smalltalk-80: https://ru.wikipedia.org/wiki/Smalltalk
[15] Борбаг: http://wiki.c2.com/?BohrBug
[16] OLCF at ORNL: https://www.flickr.com/photos/olcf/36987126853
[17] Шрёдинбаг: http://wiki.c2.com/?SchroedinBug
[18] мысленного эксперимента: https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D1%82_%D0%A8%D1%80%D1%91%D0%B4%D0%B8%D0%BD%D0%B3%D0%B5%D1%80%D0%B0
[19] мандельбага: http://wiki.c2.com/?MandelBug
[20] Бенуа Мандельброта: https://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D0%BD%D0%B4%D0%B5%D0%BB%D1%8C%D0%B1%D1%80%D0%BE%D1%82,_%D0%91%D0%B5%D0%BD%D1%83%D0%B0
[21] удаления «мёртвого» кода: https://ru.wikipedia.org/wiki/%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D1%91%D1%80%D1%82%D0%B2%D0%BE%D0%B3%D0%BE_%D0%BA%D0%BE%D0%B4%D0%B0
[22] Avito.ru: как облако IaaS помогает в организации бизнеса компании: https://iaas-blog.it-grad.ru/kejsy/hybrid-cloud-for-avito/
[23] Что нужно знать о PCI DSS: обзор стандарта: https://iaas-blog.it-grad.ru/novosti/chto-nuzhno-znat-o-pci-dss-obzor-standarta/
[24] Как изменилась жизнь с наступлением DNS Flag Day: https://iaas-blog.it-grad.ru/tendencii/mir-do-i-posle-kak-izmenilas-zhizn-s-nastupleniem-dns-flag-day/
[25] Как IaaS помогает развивать бизнес: задачи, которые решит облако: https://iaas-blog.it-grad.ru/tendencii/kak-iaas-pomogaet-razvivat-biznes-tri-zadachi-kotorye-reshit-oblako/
[26] 9 полезных советов для плавного перехода в облако: https://iaas-blog.it-grad.ru/tendencii/9-poleznyx-sovetov-dlya-plavnogo-perexoda-v-oblako/
[27] Источник: https://habr.com/ru/post/448002/?utm_source=habrahabr&utm_medium=rss&utm_campaign=448002
Нажмите здесь для печати.