На Хабре уже были подборки «самых масштабных багов в истории»: взорвавшаяся ракета Ariane-5, передозировка радиацией от Therac-25 и так далее.

Но бывают менее катастрофические ошибки, о которых тоже хочется поговорить: неожиданные ситуации, заставлявшие людей много чесать в голове. Наверняка многие читатели Хабра знают почти что апокрифическую историю про электронную почту, которую нельзя было отправить дальше чем на 500 миль. Как такое вообще может быть?

Сейчас мы готовим очередную конференцию по тестированию Heisenbug и вспомнили ещё одну загадочную историю из старого доклада с Heisenbug. Решили поискать в местах вроде Reddit другие интересные случаи. А в итоге представляем пятничную подборку очень странных дел.

Перерыв на лимонад

Такая же загадочная, как и с 500-милевой почтой, история произошла  в одной компании, разрабатывающей финансовое приложение. Вскоре после сдачи проекта служба поддержки получила заявку, в которой пользователь описывал проблему с веб-приложением вот так: «Оно падает каждый раз, когда я пью колу».

Саппорт посмеялся над заявкой и проигнорировал ее. Но пользователь упорствовал и добавлял новые сведения, что, мол, приложение работает нормально, когда он пьет кофе, а вот на кока-коле вырубается. Один из членов поддержки все же решил разобраться в проблеме.

Выяснилось следующее. Кофейный автомат находился всего в нескольких метрах от пользователя. А автомат по продаже колы — на совсем другом этаже в кафетерии, так что отправляясь туда, пользователь тратил ощутимое время. А в онлайновой веб-форме была функция тайм-аута, которая заставляла приложение разлогиниваться, если со страницей не взаимодействовали более 15 минут.

В общем, даже когда пользовательский баг-репорт на первый взгляд кажется абсурдным, не стоит сразу отметать его со словами «глупый пользователь».

Перерыв на кубики

А вот перекликающаяся история. Ещё в 2017-м на Heisenbug Андрей Солнцев рассказывал (в отдельном хабрапосте можно прочитать подробнее):

«Детективное расследование длиной в два года, абсолютно реальный случай. Ситуация такая: наши тесты довольно часто были flaky и падали, и в стек-трейсах было видно, что Chrome зависает: не тест наш, а именно Chrome. Пытались сделать всё, что только может прийти в голову — проблема лишь стала возникать ещё чаще. 

Попытались воспроизвести проблему: пишем цикл от 1 до 1000, в цикле просто открываем браузер, первую страничку в нашем приложении и закрываем. Написали такой цикл, и… бинго! Результат: проблема стала повторяться стабильно (правда, примерно через каждые 80 итераций)! Круто! Правда, это достижение долго ничего не давало. Запустил ты, дождался 80-й итерации, завис Chrome… а дальше что делать? Смотришь в стек-трейсы, дампы, логи — ничего полезного там нет. 

И тут в этой истории начинается сказочный момент. Однажды, после бесконечного количества попыток, я снова запустил эти тесты, он у меня снова на какой-то итерации вроде 56-й завис, я думаю «давай ещё что-нибудь покопаю» (правда, не знаю, куда ещё брейкпойнт поставить или какой-то лог добавить). В этот момент дочка предлагает поиграть в кубики, а у меня тут как раз тест завис. Я говорю «Подожди», она мне: «Ты что, не понял, у меня тут к у б и к и

Что поделать, с грустью оставил компьютер, пошёл играть в кубики… И вдруг, примерно через 20 минут, случайно бросаю взгляд на экран, и вижу совершенно неожиданную картину:

Что получается: идёт отсчёт, через сколько минут истечёт сессия, а я строю башню из кубиков, остаётся две, одна… сессия истекает, тест продолжается, бежит до конца и падает (элемента уже нет, сессия истекла).

Что получается: Chrome на самом деле не зависал, как мы думали всё это время, он всё это время что-то ждал. Когда сессия истекала, дожидался, шёл дальше». 

Смотрите, как (не) надо

Реддитор Xantoxu решил провести серию стримов по программированию и на примере создания игры рассмотреть некоторые концепции написания кода. Он хотел научить людей хорошим методам программирования, логике, организации кода, основам искусственного интеллекта и балансировки игры, и все в таком духе. Для этого он выбрал простую текстовую игру для консоли Windows, и там делал всякие интересные штуки.

Во время отладочного стрима реддитор специально вставлял в код ошибки, чтобы показать, как правильно читать ошибки, которые выдает компилятор. Все шло прекрасно. Он объяснял, что значат те или иные выводы компилятора и рассказывал как тестировать свою игру. Но в каком-то куске кода забыл поставить точку с запятой. Правда, забыл. Это не входило в планы. Компилятор начал ругаться, и стримеру понадобился целый час, чтобы понять, что не так.

То есть он целый час искал ошибку на стриме по работе с ошибками. Наверняка зрители были в восторге.

Баг? Я звоню в полицию

А вот история из 1995 года. Один реддитор zircofluoride работал в стартапе, где создавал embedded-систему со встроенным телефонным номеронабирателем, где использовался тональный набор (Dual-Tone Multi-Frequency, DTMF).

Схема кодирования DTMF располагает цифры 0–9, #, * (и A–D) в матрице 4x4 с разной частотой для каждой строки и столбца. Суть программы была в том, что прошивка генерирует частоту строки на одном GPIO, а частоту столбца — на другом GPIO, аппаратура смешивает тоны и подает результат на телефонную линию.

Реддитор написал код генерации DTMF, а также тестовую программу, которая циклически перебирала цифры от 9 до 0, затем от 0 до 9, затем от 9 до 0 и т. д. Но когда пришло время протестировать код, руководство решило отказаться от покупки симулятора оператора связи и просто попробовать его на линии старых обычных телефонных служб, используемых для факсимильного аппарата.

Оказалось, что код использовал неправильные частоты для всех частот, кроме одного столбца и двух строк, соответствующих цифрам 1 и 9, и программа эффективно набирала 9-1-1 снова и снова. Через четыре минуты после запуска кода в офисе появились полицейские с оружием наготове.

Когда маркетинг лезет в разработку

А вот еще одна старая драматическая история, без стрельбы, но почти с детективным сюжетом.

Один программист работал в компании, которая генерирует отчеты со статистикой по медицинскому ПО и оборудованию. Долгое время команда разработки занималась миграцией сайтов на MVC ASP.NET. В числе прочего сделали логирование, и поначалу всё шло хорошо, число ошибок становилось меньше с каждым днем.

А потом в какой-то момент возникла проблема, и страницы сайтов стали творить непонятную дичь, а база данных работать с перебоями. К концу дня база не отвечала вообще. Разработчики делали экстренный дебаг, пока остальные сотрудники расходились по домам. Постепенно удалось понять, что сервис логинга ошибок на стороне клиента сходил с ума, логируя снова и снова одну и ту же ошибку — с такой частотой, что система не выдерживала. Но ошибка, которая попадала в репорты, выглядела абсурдной, и никто не мог понять, в какой части кода проблема. Разработчики временно удалили код логинга и начали подозревать, что сайт взломан.

А утром один менеджер из отдела маркетинга проболтался, что сам добавил проблемный код на сайт. Он проигнорировал существующий процесс по деплою и выложил на сервер код, которого не было в системе контроля версий, и никто не знал про это. Это был баннер с бегущей строкой, сделанный на JS и взятый откуда-то из интернета.

Этот простой код постоянно исполнялся, и отчет генерировался буквально каждую итерацию. Логирование, которое внедрила команда, не содержало никакого средства против подобного «спама» и отправляло на сервер тысячи запросов, что блокировало браузер и валило серверы. Не стоит и говорить, что эту чуму снесли с сервера, а менеджера ждал серьезный разговор с директором.

Не фича, а баг

А бывает так, что реализованные и корректно работающие (с точки зрения разработчика) функции в итоге убираются, потому что они хуже багов.

Самый известный пример — это помощник Скрепыш (Clippy) в пакете MS Office. 

Поначалу Clippy казался безобидным офисным помощником. Но пользователей он бесил и раздражал. Есть даже дипломная работа на тему того, почему люди ненавидят несчастную Скрепку (спойлер: потому что она заставляет чувствовать себя беспомощным).

В итоге Microsoft удалила Скрепку из системы. И фактически рекламировала тот факт, что в новой версии Office ее нет. Мол, в Office XP настолько все просто и понятно, что помощник просто будет сидеть без работы. Вот так фича стала багом и даже вошла в топ-50 худших изобретений вместе с ДДТ и водородными дирижаблями.

В истории разработки найдется много историй о продуктах, провалившихся из-за недостаточного качества. Здесь и эппловская ОС Copland, и Netscape Navigator 6.0, и забагованные игры.

Не баг, а фича. Развенчиваем миф про грудь Лары Крофт

И раз уж мы упомянули игры напоследок побудем разрушителями легенд.

Есть городская легенда, объясняющая откуда взялся оригинальный образ Лары Крофт с большой грудью. Якобы Тоби Гард — художник-аниматор — случайно установил слишком большое значение и заметил это слишком поздно, уже когда надо было сдавать работу. А менеджерам настолько понравился образ большегрудой красотки, что они решили так и выпускать.

В 1997 Тоби Гард давал интервью журналу The Face, и когда журналист спросил про размеры груди Лары Крофт, Тоби саркастически ответил, что у него дрогнула рука с мышью и он случайно установил такое значение. Это была очевидная шутка.

Но затем журнал GameSpot опубликовал статью (1 апреля, между прочим) про «ужасную ошибку», и понеслась. 

Но на самом деле все это было часть запланированной маркетинговой компании, и подобный образ Лары Крофт помогал продавать продукт. Хотя и без багов в игре тоже не обошлось.

Вывод

Можно ли сделать из всего написанного выше какие-то выводы? Случаи слишком разные для категоричных общих заявлений, но можно выделить что-то в таком духе:

  • В тестировании полезно уметь «think outside the box»: иногда правильные ответы бывают очень неочевидными и контринтуитивными.

  • Всем, у кого есть доступы со стороны разработки, стоит помнить, что правила придуманы не просто так: не знаешь брод — не суйся в прод.

  • А отвлечься от тестирования и поиграть с ребёнком в кубики бывает полезно не только для семьи, но и для тестирования.

Мы пойдём дальше готовить Heisenbug: его онлайн-часть начнётся уже в понедельник. А 21 июня у него будет отдельный офлайн-день в Петербурге. Программу можно увидеть на сайте, билеты — там же.

Будем рады увидеть вас и в онлайне, и в Питере!

Комментарии (21)


  1. Aleksandr-JS-Developer
    27.05.2022 19:38
    +8

    Оно падает каждый раз, когда я пью колу ... приложение работает нормально, когда он пьет кофе, а вот на кока-коле вырубается

    В голове сразу мужик за офисным креслом с кока-колой в руке и в момент самого пития приложение падает. Я не понимаю людей для которых фраза, например, "съесть печенья" значит не "Взял печеньку в руку. Съел. Всё.", а "Поставил комп в сон, заварил кофе, намазал печенье маслом, заправил джемом, вышел на балкон и посидел там, покушал печенье, потом перемыл 10шт посуды"...


    1. MedicusAmicus
      27.05.2022 19:48
      +1

      Не считая того, что баг был на уровне требований, и не предусмотрели вывод пользователю адекватного сообщения о конце сессии.


      1. alex-khv
        27.05.2022 22:19
        +1

        Если перейти по ссылке, там подробнее описано. Во время авто-завершения сессии веб-приложение пыталось сохранить поля в форме, но пустые поля с обязательным заполнением приводили к исключению.


  1. daryamal
    27.05.2022 19:52
    +8

    Дипломная работа по Скрепышу - это самое прекрасное что я узнала за сегодня


  1. DanilinS
    27.05.2022 19:56
    +6

    Было нечто похожее.

    Писал код на Дельфях с глубоким взаимодействием с виндузовым API. А там при малейшей ошибке как у сапера: повезло, если при ошибке просто приложение легло. Бывало и Дельфя за компанию вылетала. Или винда в синий экран улетит.

    И в один момент получаю очень странное сообщение о ошибке. Если перевести там было "Данная ошибка даже теоретически не может возникнуть. Если вы видите данное сообщение - сообщите разработчику. ". По видимому случайно зацепил что-то не то в среде программирования.


    1. MFilonen2
      27.05.2022 20:31

      Встречал что-то такое, по-моему, в ноде.
      Хорошая практика кстати – разделять ошибки клиента и внутренние ошибки самой программы.
      Правда, в обоих случаях приходится искать обходной путь…


    1. alex-khv
      27.05.2022 22:22
      +2

      Я как-то в студенчестве программировал в турбо-паскале под досом загрузившись с дискетки (жд сломался). Надо ли говорить что при любой ошибке в коде приводящей к зависанию, терялся весь не сохраненный код. В итоге на всю жизнь привычка сохраняться в любых текстовых редакторах! И не важно, код это или заявление в ворде ????


      1. Radisto
        28.05.2022 08:48
        +1

        Пятый маткад приучал к тому же самому. Тоже часто вис, не сохраняя ничего.


  1. ED-209
    27.05.2022 20:18

    «Оно падает каждый раз, когда я пью колу»

    На IXBT форуме в разделе технической помощи как-то давно проскакивало:

    Мышь и клавиатура перестают работать из-за газовой плиты на кухне

    В теме разобрались, но заголовок так и отложился в памяти :)


  1. Yuribtr
    27.05.2022 21:41
    +15

    Баян конечно, но вдруг кто не слышал:

    Деревенская бабка вызвала телефонного мастера. Мастер приходит:

    - Что случилось?

    - Мне говорят что я очень долго не подхожу к телефону, не все дожидаются и бросают трубку думая что меня нет. Но я к телефону сразу подхожу! Ещё почему-то собака скулит всегда перед самым звонком. Она ясновидящая?

    Мастер открыл распределительный шкаф, достал мобильник и позвонил бабке. Телефон зазвонил не сразу, а только после того, как собака заскулила. Покопавшись в проводах мастер выяснил что:

    * Собака привязана к заземлению телефонного провода железными цепью и ошейником;

    * Заземлитель плохо присоединён к громоотводу, разрывая, тем самым, цепь;

    * Собака получала 90 вольт при входящем звонке;

    * После нескольких ударов тока собака начинала скулить и писалась;

    * Увлажнённая земля замыкала цепь и телефон звонил.


    1. sparhawk
      27.05.2022 23:23
      +1

      Помнится в 00-х в квартире перетерся телефонный провод, но не оторвался совсем. Обычный телефон перестал работать, а ADSL худо-бедно и нестабильно продожал работать на низкой скорости. Видимо, этот почти-разрыв превратился в фильтр высокой частоты.


    1. sukhe
      28.05.2022 19:46

      Бедная собака… Меня как-то долбануло входящим телефонным звонком. И это было намного-намного больнее, чем 25 кВ с кинескопа или 600В с анода передатчика.


  1. connected201
    28.05.2022 10:58

    функция тайм-аута, которая заставляла приложение разлогиниваться, если со страницей не взаимодействовали более 15 минут.

    я много где встречал в банковских проложениях такую систему, она и сейчас есть. (что бы злоумышленник не смог воспользоваться открытой сессии).


  1. lxsmkv
    28.05.2022 13:32
    +3

    Читал как-то историю рассказанную Реймондом Ченом из Майкрософта:

    В офисе поменяли поставщика молока для кухни. Выяснилось, что новые пачки с порционным молоком* трудно открываются. В сервис был написан багрепорт следующего содержания:

    Баг:Новые пачки с молоком трудно открываются
    Как воспроизвести: Пойти на кухню, взять новую пачку с молоком и попытаться ее открыть, затем взять салфетки у вытереть лужу с пола.

    Причина же проблемы была в том, что компания-производитель недавно купила новые машины для производственной линии, которая запаивала пачки используя слишком много клея. Когда автоматы настроили проблемы прекратились.

    Были предложены обходные решения, включая такие как приходить на работу со своей коровой, а так же трехступенчатый способ состоящий из замораживания молока с последущим разрезанием упаковки и оттаиванием содержимого. Некоторые даже настаивали на недостаточном объеме тестирования, поскольку три тестировщика привязаных к этому компоненту, могут выпить только 8 упаковок молока в день. По их мнению необходимо было провести дополнительные виды тестирования молока, а также обязятельно аудит безопасности по причине понижения силы склеивания после перенастройки оборудования.

    * - прим. перев.
    * -видимо имеются ввиду подобные упаковки с гребешком
    * -видимо имеются ввиду подобные упаковки с гребешком


  1. aMster1
    28.05.2022 17:15
    +4

    Старая история :

    В 1978 году в отдел Pontiac автомобильного гиганта General Motors пришло письмо: «Вы, сочтете меня сумасшедшим, но уверяю, это не так. Наша семья очень любит мороженое, поэтому по вечерам дети выбирают, то какое они хотят, и я еду за ним. И вот я приобрел ваш новый "Pontiac". И честное слово, когда я беру ванильное мороженое, машина перестает заводиться! Если мороженое клубничное, шоколадное или любого другого сорта — нет проблем. Я понимаю, что это безумие, но что-то в этом авто реагирует на ванильное мороженое? В службе поддержки посмеялись над письмом, но согласно регламенту, обязаны были отправить инженера на проверку

    Хозяином машины оказался адекватный, воспитанный и образованный человек. Инженера это очень удивило. Они отправились в магазин, купили ванильное мороженое. И правда – Pontiac не заводится! Эксперимент продолжался несколько дней и результаты были невероятны! Шоколадное – заводится. Клубничное – заводится. Ванильное – нет. Инженер был человеком образованный и не хотел верить, что у автомобиля аллергия на ваниль. Он отследил все детали: время, бензин, заправку даже погоду

    И выяснилось: дело не в ванили и не в мороженном, а в размещении товара в магазине. Ванильное мороженое, как самое популярное, выкладывали в холодильнике у самого входа, а остальное – в глубине зала. Купить ванильное можно было гораздо быстрее, чем другое..

    И почему тогда авто не не заводится, если хозяин возвращается быстрее? Ответ был найден: двигатель не успевал остыть, и в карбюраторе оставались пробки, вызванные интенсивным испарением бензина .....»


    1. randomsimplenumber
      29.05.2022 09:16

      Если машина используется только для поездок за мороженым в ровно 1 супермаркет - всё выглядит правильно. А так, повторный пуск неостывшего двигателя - насколько частый случай в эксплуатации автомобиля, что странно было бы не заметить, что двигатель точно так ведёт себя после погрузки-выгрузки чемодана из багажника, или после открытия ворот гаража, например.


      1. Tarakanator
        30.05.2022 14:57

        Насколько я понимаю проблема возникает только при определённом времени простоя. При времени простоя меньше определённого(выгрузка чемодана) проблема не воспроизведётся.


  1. lxsmkv
    28.05.2022 19:50
    +1

    А вот еще одна история которую рассказал пользователь с ycombinator:

    Клиенту в городе Боулдер, штат Колорадо, поставили новый серверный кластер. Пошли заявки о том что связь между серверными узлами прерывается при большой нагрузке поздним днем. Его послали на диагностику. Два дня безрезультатных попыток воспроизведения, но как только он уехал ему сообщили на пейджер, что проблема снова возникла.
    Изначально было предположение, что это связано сo сбоями отдельных ядерных частиц (SEU - Single Event Upset), поскольку в этом регионе подобные проблемы были сравнительно частым явлением. Но необходимые корректировки для предотвращения этого были уже проведены. Поэтому эта теория отметалась.
    Оказалось, что сбоила система охлаждения, поскольку в этой области воздух более разреженный (>1600м н.у.м.) и соответственно имеет пониженную способность к транспортировке тепла. Но перегревались не процессоры, а блоки питания. При перегреве, они теряли мощность. Таким образом, послеполуденный зной провоцировал падение мощности и нестабильность в работе серверных узлов. При перезапуске все снова работало нормально потому, что этого небольшого перерыва было достаточно чтобы дать блокам питания немного остыть. Починили проблему добавлением одной строчки в конфигурацию контроллера вентилятора.


  1. sukhe
    28.05.2022 20:00
    +2

    Ха! Час искал ошибку на стриме про ошибки. Я как-то час не мог найти ошибку в программе, в которой вообще не было ошибки!

    Пишу программу. Элементарную, каких уже десятки написаны. Выдаёт ошибку в первой же строке. Как-так? Простейшая команда из трёх букв, ошибиться просто невозможно.

    Перегружаюсь. Переписываю начало программы заново, переименовываю файл, переключаю раскладки, призываю Ктулху — ничего не помогает. Зову на помощь коллег. «Вот программа, где ошибка?» «Да нет здесь ошибок! Как тут вообще можно ошибиться?»
    Психую, иду успокаивать нервы чайком.

    Возвращаюсь. Сажусь за комп. И тут до меня наконец доходит... Программа написана на Clipper, а я её пытаюсь запустить под C++!!!

    Мы тогда как-раз переползали с одного на другое и одновременно использовали два языка.


    1. randomsimplenumber
      29.05.2022 07:17

      Программа написана на Clipper, а я её пытаюсь запустить под C++!!!

      Python 2 to python 3 ;)


  1. stalinets
    29.05.2022 01:58
    +2

    Читал байку про то, как человек долго не мог найти источник странных периодически преследующих его звуков. Менял колонки и кабели, переставлял драйвера на звуковую карту, искал вирусы. Оказалсь - это собачка, помощник в WinXP, периодически проигрывает анимацию с чесанием себя лапой, и это чесание озвучено.