- PVSM.RU - https://www.pvsm.ru -

Что такое гейзенбаг: история термина и примеры

Это — справочный материал о гейзенбагах. Говорим о том, как они выглядят и какое отношение имеют к мейнфреймам — прародителям облака.

Что такое гейзенбаг: история термина и примеры - 1 [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 году предложил простую и понятную модель строения атома. Согласно этой модели, электроны атома двигаются по определенным орбитам, значит, их импульс и радиус движения можно предсказывать. Аналогично, появление борбагов можно предсказывать, если создать для них нужные условия.

Что такое гейзенбаг: история термина и примеры - 2
/ фото OLCF at ORNL [16] CC BY

Шрёдинбаг [17] — ошибка, которая существует и не существует одновременно, пока на нее не посмотрит разработчик. Название ошибка получила в честь известного мысленного эксперимента [18].

Что касается мандельбага [19], то это ошибка, из-за которой система ведет себя хаотично и непредсказуемо. Феномен назван в честь физика, математика и создателя фрактальной геометрии Бенуа Мандельброта [20].

Что в итоге

Примеров гейзенбагов (и других *багов) — множество [13]. Их очень сложно искать, но причины возникновения обычно банальны: неинициализированная переменная, ошибки синхронизации в многопоточной среде или проблемы с алгоритмами удаления «мёртвого» кода [21]. Получается, что для борьбы с подобными ошибками их нужно отсекать еще на этапе проектирования приложения.


Из блога о корпоративном IaaS:

Автор: ИТ-ГРАДовец

Источник [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