Луна убывает, такое бывает… ©Земфира
Гейзенбагом называют ту разновидность программных глюков, которая возникает не пойми откуда, не поддается отладке и обнаружению. Словом, ведет себя как тот самый Неуловимый Джо или кроковский кот из недавнего поста. Мне по работе приходилось сталкиваться с такими и про себя я называл это эффектом квантовой механики до тех пор, пока не узнал, что близкое по смыслу название уже давно придумали. Бывает, посылаешь заказчику отладочный бинарник, который всего лишь записывает в журнал больше событий вокруг предполагаемого источника проблемы и после этого проблема исчезает!
heisenbug /hi:'zen-buhg/ n.
A bug that disappears or alters its behavior when one attempts to probe or isolate it.
Предлагаю вашему вниманию свою небольшую познавательную коллекцию квантовых эффектов в программировании.
Эпизод I, OpenOffice не печатает во вторник
Историю этого замечательного багрепорта можно почитать на Ubuntu Launchpad, а я вкратце изложу суть для тех, кому не сподручно читать по ссылке. В системной утилите file
был баг из-за которого, файлы содержащие в 4-м байте Tue
определялись как Erlang JAM. Дефект присутствовал в версиях file
4.21 и 4.24 и был вызван ошибкой в magic
файле.
anon@x-X:~$ echo "1/2 Tue" >> file && file file
file: Jan 22 14:32:44 MET 1991\011Erlang JAM file - version 4.2
anon@x-X:~$ file --version
file-4.21
magic file from /etc/magic:/usr/share/file/magic
Это приводило к тому, что по вторникам для бажной версии file
временные отметки PostScript файлов были похожи на Erlang JAM.
%%CreationDate: (Tue Mar 3 19:47:42 2009)
При отправке задания на принтеры семейства Brother, OpenOffice запускал процедуру проверки PostScript файла, которая завершалась ошибкой, потому что обнаруживала тип файла Erlang JAM. Исправление, в основном, свелось к экранированию пробела.
+# 4.2 version may have a copyright notice!
-+4 string Tue Jan 22 14:32:44 MET 1991 Erlang JAM file - version 4.2
-+79 string Tue Jan 22 14:32:44 MET 1991 Erlang JAM file - version 4.2
++4 string Tue\ Jan\ 22\ 14:32:44\ MET\ 1991 Erlang JAM file - version 4.2
++79 string Tue\ Jan\ 22\ 14:32:44\ MET\ 1991 Erlang JAM file - version 4.2
Впрочем, и с бажным file
проблема устранялась просто, однако к тому моменту гейзенбагу уже исполнилось 9 месяцев!
sed -e '/^%%CreationDate:/s/Tue/tue/' > $INPUT_TEMP
Эпизод II, Луна и Perl
Однажды на просторах сети мне попался этот прекрасный экземпляр ИТ юмора. Изнывая от скуки, разработчик Debian решил вычислить зависимость багрепортов от фазы Луны и быстренько написал такой скриптец.
#!/usr/bin/perl -w
use strict;
use warnings;
use constant PI => 3.1415926535;
use feature "say";
use SOAP::Lite;
use Astro::Coord::ECI::Moon;
my $soap = SOAP::Lite->uri('Debbugs/SOAP')->proxy('http://bugs.debian.org/cgi-bin/soap.cgi');
if (!defined($ARGV[0])) {
die "E: must have a source package!\n";
}
my @bugs = $soap->get_bugs(src=>$ARGV[0])->result();
my $bugsdata = $soap->get_status(@bugs)->result();
my $moon = Astro::Coord::ECI::Moon->new();
my %count = ( 'new' => 0, 'first' => 0, 'full' => 0, 'last' => 0);
foreach my $bug (keys %$bugsdata) {
my $time = $$bugsdata{$bug}->{date};
my $phase = $moon->phase($time);
if ($phase <= 45 * PI / 180 || $phase > 315 * PI / 180) {
$count{'new'} = $count{'new'} + 1;
} elsif ($phase <= 135 * PI / 180 && $phase > 45 * PI / 180) {
$count{'first'} = $count{'first'} + 1;
} elsif ($phase <= 225 * PI / 180 && $phase > 135 * PI / 180) {
$count{'full'} = $count{'full'} + 1;
} elsif ($phase <= 315 * PI / 180 && $phase > 225 * PI / 180) {
$count{'last'} = $count{'last'} + 1;
}
}
say "Number of bug submissions during new moon : " . $count{new};
say "Number of bug submissions during first quarter: " . $count{first};
say "Number of bug submissions during full moon : " . $count{full};
say "Number of bug submissions during last quarter : " . $count{last};
Результат для пакета nbd
был обнадеживающим, зависимость явно проклевывалась.
wouter@carillon:~code/perl$ ./debbugsmoon nbd
Number of bug submissions during new moon : 2
Number of bug submissions during first quarter: 10
Number of bug submissions during full moon : 1
Number of bug submissions during last quarter : 3
Для наукообразности можно даже в R
проверить гипотезу функциональной зависимости. Данных маловато, но цифры внушают — p-value = 0.005853
.
> chisq.test(c(2, 10, 1, 3));
Chi-squared test for given probabilities
data: c(2, 10, 1, 3)
X-squared = 12.5, df = 3, p-value = 0.005853
Предупреждение:
В chisq.test(c(2, 10, 1, 3)) :
аппроксимация на основе хи-квадрат может быть неправильной
Я решил повторить эксперимент спустя 6 лет, и что бы вы думали?
[5153:23311 0:604] 06:09:39 Вс авг 28 [mikayel@redeye: +4] ~
(4:604)$ ./debbugsmoon.pl nbd
Number of bug submissions during new moon : 1
Number of bug submissions during first quarter: 12
Number of bug submissions during full moon : 3
Number of bug submissions during last quarter : 1
С этим nbd
что-то явно не так, лунные фазы теперь давят сильнее!
> chisq.test(c(1, 12, 3, 1))
Chi-squared test for given probabilities
data: c(1, 12, 3, 1)
X-squared = 19.471, df = 3, p-value = 0.0002185
Предупреждение:
В chisq.test(c(1, 12, 3, 1)) :
аппроксимация на основе хи-квадрат может быть неправильной
Возможно, найдутся примеры и поярче, если проверить все 43 тысячи пакетов Debian Linux, но думаю это будет не лучшей тратой времени.
Эпизод III, Луна и LISP
Плохому танцору не всегда удаются сложные па, а программистам изредка гадит Луна. Нам об этом известно, благодаря хакерам старой школ, издавшем в 1983-м г. Словарь Хакера, у которого есть и другое название — the Jargon File. С тех пор книга выдержала еще несколько изданий и стала своего рода классикой жанра. В статье Phase of the Moon [1] есть довольно занятная байка на тему.
Однажды, Guy Steele [2], в то время еще студент MIT, словил баг в коде MacLisp [3], записывающей временные метки в отдельный файл содержащий формы, включив туда стандартную функцию приближенного вычисления фазы Луны. По неподтвержденным данным бажную программу также писал Gerry Sussman [4]. Изредка программа сбоила, причем случалось это каждый месяц в одно и то же время из-за того, что первая запись выкатывалась на новую строку, не обозначая комментарий символом ";". Длина первой записи зависела от временной метки и определенной фазы, то есть превышала широту страницы в 80 символов в зависимости от лунного календаря!
В той же статье упоминается еще один случай, когда в ЦЕРН сбоила программа обсчета результата экспериментов на ускорителе LEP коллайдера [5]. Долгие поиски причин сбоев наконец-то привели к разгадке. Кольцо периметра LEP, в 27 км. длиной, было очень незначительно деформировано из-за гравитации Луны. Эта история стала частью фольклора в среде физиков, получив название Ньютоново Возмездие. За достоверность деталей этой истории не могу поручиться, так как т. н. приливные деформации известны уже десятки лет как. Хотелось бы узнать мнение Хабра на этот счет.
Эпизод IV, мой Гейзенбаг
Был у меня на старом ноуте совершенно безумный баг, который приводил к полному или частичному зависанию ОС в время прослушивания музыки через USB наушники, причем чаще всего к зависанию приводило прослушивание интернет-радио. Я это терпел пару-тройку лет а затем, поняв, что ничего не меняется от смены версий ядра Linux, Xorg и драйверов, отправил багрепорт в Gentoo Bugzilla.
This happens for already 4 years with kernels starting 2.6.20 to 2.6.31. Similarly it happened on «HP nc 6220» based no intel chipset running «Debian Linux 5.x.» again USB headphones were Plantronics DSP 300.
Surprisingly it never happens under liveCD, I tested few times keeping audio-streaming for 1 hour and nothing crashed.
В вольном переводе, это жалоба на то, что гейзенбагу уже 4 года и он одинаково хорошо себя чувствует на версиях Linux ядра с 2.6.20 по 2.6.31, на чипсете AMD Radeon Xpress 200M и интеловском 915GM, но почему-то не прижился на LiveCD дистрибутивах.
В момент зависания нигде сообщения об ошибке не возникало и только в /var/log/messages
появлялась запись: N URBs still active
, где N — четное число < 10. Скорее всего падеж происходил в модуля ядра snd_usb_audio
, небрежно обрабатывался и приводил систему в ступор.
Последняя запись в багрепорте, что я поменял опции аппаратного ускорения для открытого графического драйвера radeon
Option "AccelMethod" "EXA" #было
Option "AccelMethod" "XAA" #стало
после чего проблема испарилась, но непонятно как и зачем, ведь это изменение никаким образом не связано с snd_usb_audio
.
- ↑ Автор так обозначил разновидность Гейзенбага. По ссылке, the Jargon File, версия 4.3.3.
- ↑ Автор книги Common Lisp the Language, один из создателей языка програмимрования Scheme.
- ↑ Диалект языка программирования Lisp, разработанный в лаборатории искусственного интеллекта MIT.
- ↑ Один из создателей языка программирования Scheme, со-автор книги Structure and Interpretation of Computer Programs.
- ↑ Большой электрон-позитронный коллайдер.