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

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

▍ ✈️ Кейс 1. Авария ракеты-носителя «Ариан-5»


Четвёртого июня 1996 года Европейское космическое агентство (European Space Agency, ESA) впервые запустило ракету «Ариан 5», отметив важный момент в истории исследования космоса. Однако миссия оказалась провальной, поскольку буквально одна строка кода привела к катастрофическому сбою и потере всего груза стоимостью почти полмиллиарда евро.


Ракета «Ариан 5» (фр. Ariane 5)

Эта ракета должна была доставить два спутника связи на геостационарную переходную орбиту. Запуск шёл гладко, пока ракета не отклонилась от траектории и не разрушилась на 37 секунде полёта. Было установлено, что причиной катастрофы стал программный сбой в системе наведения, которая отвечала за регулирование курса полёта ракеты. Сбой при запуске Ариан-5 был признан одним из самых дорогостоящих в истории ПО. Разрушение научных спутников привело к задержке исследований магнитосферы Земли почти на 4 года.

В чём же была причина? Мёртвая часть кода программы из последней миссии Ариан-4, которая стартовала примерно 10 годами ранее, содержала простую и вполне исправимую ошибку. Ракета определяла свою направленность движения вверх или вниз с помощью метода, известного как горизонтальное смещение, иногда также называемого «BH value». Его значение представлялось 64-битной переменной с плавающей запятой, которую система наведения использовала для преобразования в 16 16-битных знаковых целых. 64-битная переменная может представлять миллиарды значений, в то время как 16-битная может выражать лишь 65 535.

Нам известно, что в целых числах первый бит представляет знак, и что 16-битные целые могут находиться в диапазоне от -32 768 до 32 767. При этом числа с плавающей запятой создаются для отслеживания более широкого диапазона значений, используя то же количество битов между -1.8e+308 и -2.2e-308. Если вы попытаетесь сохранить такое значение в 16-битном целом числе, то оно значительно выйдет за его допустимые границы. По итогу в программном обеспечении ракеты произошло хорошо известное целочисленное переполнение.

Катастрофа Ариан-5

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

Какие ключевые выводы можно сделать из этой катастрофы?

  • Копирование кода без его понимания (карго-культ) представляет серьёзную проблему.
  • Ещё одна проблема — это отсутствие подобающей обработки ошибок.
  • Пренебрежение изменениями, внесёнными по требованию операторов, и
  • Отсутствие необходимого тестирования.

В итоге комиссия по расследованию составила следующие рекомендации:

  • R1 — избегать использования программ или систем, которые не являются обязательными. Во время полёта программное обеспечение не должно выполняться, если на то нет необходимости.
  • R2, R10, R11 — критически необходимо проводить тестирование. Организуйте тестовую среду с максимальным объёмом тестового оборудования и проводите тщательное тестирование системы в закрытом цикле. Всем миссиям должны предшествовать полноценно реализованные симуляции с обширным покрытием тестами.
  • R4 — проводить код-ревью. В любом языке программирования важны все детали кода.
  • R6, R8 и R13 — необходимо повышать читаемость за счёт обработки исключений в задачах и создания резервных механизмов для поддержания стабильной работы во время сбоев. При определении критических компонентов важно также учитывать возможные программные сбои. Организуйте команду для выработки строгих правил тестирования ПО, обеспечивающих следование высококачественным стандартам.

Информационные ссылки:


▍ ✈️ Кейс 2. Как неперехваченное SQLException остановило работу авиалиний


В январе 2023 года агентство Reuters поведало об интересном инциденте, произошедшем в Федеральном управлении гражданской авиации (Federal Aviation Administration, FAA). В ходе анализа происшествия специалисты управления выяснили, что работающий по контракту специалист «непреднамеренно удалил файлы», вызвав общенациональный запрет на вылеты 11 января. Если говорить точнее, в тот день оказалось отменено более 11 000 полётов. Представители управления сообщили, что этот сотрудник работал над синхронизацией основной и резервной баз данных.

Это напоминает мне о проблеме, о которой рассказывается в главе 2 книги «Release It» Майкла Найгарда. Авиалинии планировали произвести аварийное переключение кластера базы данных, выступавшего основной системой, выстроенной по принципу сервис-ориентированной архитектуры. Этот поэтапный переход был запланирован и распределён по функциональности. Названная система обрабатывала поиск, возвращая для разных запросов (дата, время, город) детали перелётов.

Программное обеспечение авиалинии работало на кластере прикладных серверов J2EE с БД Oracle, обеспечивавшей резервную избыточность данных, и аналогичными аппаратными балансировщиками нагрузки, которые на тот момент представляли распространённую высоконадёжную архитектуру. Однажды инженеры выполнили ручной аварийный переход с Database 1 на Database 2 (первый резерв). Они проделывали это много раз, и всё прошло в точности, как планировалось. Затем, спустя 2 часа, система перестала обслуживать запросы, отображавшиеся на их интерактивных терминалах. После некоторого анализа они решили перезапустить приложения, что привело к проблеме, остановив работу авиалиний примерно на 3 часа.

После аварийного анализа журналов, дампов потоков выполнения и файлов конфигурации инженеры обнаружили проблему в основной системе, а не в той, откуда поступали сообщения об ошибках. Многие потоки оказались заблокированы в ожидании ответа, который так и не поступал (в методе, выполнявшем поиск по городам). Они выяснили, что завершающая инструкция SQL, выполнявшаяся в заключительном блоке, может также выбрасывать SQLException, когда привод пытается запросить от базы освобождение ресурсов. В итоге этот его запрос не обрабатывался, приводя к исчерпанию пула доступных ресурсов.

Что ещё они могли предпринять в этой ситуации? Невозможно предотвратить все ошибки. Некоторые баги неизбежны. Мы лишь можем предотвратить влияние ошибок одной системы на другую.

Книга “Release It!”, Michael T. Nygard

▍ ✈️ Кейс 3. Катастрофа Boeing 737 MAX


В октябре 2018 и марте 2019 года потерпели крушение два Boeing 737 MAX, в результате чего погибло 364 человека. Отчасти причиной этого стала программная система, созданная для повышения безопасности полётов.


Boeing 737 MAX 9

MCAS — Maneuvering Characteristics Augmentation System (система повышения манёвренности самолёта) — стала камнем преткновения в истории с Boeing 737 MAX. Созданное из необходимости, это программное обеспечение стало решением внутреннего недочёта дизайна (а именно программным исправлением аппаратной проблемы [1]). Модель 737 MAX, оснащённая расширенными, более экономичными по топливу двигателями, имела иные аэродинамические свойства, нежели её предшественники. MCAS должна была позволить этой модели обрабатывать те же нагрузки, что обрабатывали прежние модели линейки 737, при этом обеспечивая лёгкую адаптацию пилотов к новшеству.

В теории MCAS была элегантна. Она автоматически корректировала горизонтальный стабилизатор, предотвращая сваливание самолёта при крутых поворотах и низких скоростях. На практике же эта система стала наглядным примером того, как единая точка отказа может вызвать каскадный катастрофический эффект.

Критический недочёт? MCAS опиралась на вводные данные лишь одного из двух датчиков угла атаки (angle of attack, ATA) самолёта [2], [3]. В случае передачи этим датчиком некорректных данных произошло бы ложное срабатывание MCAS, что привело бы к наклону носа самолёта вниз даже тогда, когда это не нужно. Дополнительно усложняя проблему, система бы срабатывала повторно, потенциально вводя в недоумение пилотов, которые не были в должной степени осведомлены о её существовании или поведении.


Установив более крупный двигатель, компания Boeing изменила аэродинамические характеристики модели 737. (Источник: NOREBBO.COM)

Однако история про MCAS не будет завершённой без освещения фактов, которые вскрылись после крушений. Впоследствии было заявлено, что компания Boeing поручила значительную часть разработки ПО для модели 737 MAX сторонним инженерам, которым платили всего по $9/час [4]. Как сообщили бывшие инженеры ПО этой компании, она всё больше начинала полагаться на временных сотрудников, в частности, недавних выпускников колледжей, услуги которых предоставляли зарубежные центры разработки ПО. Это решение, скорее всего принятое в свете необходимости сокращения расходов и ускорения разработки, привносит ещё один уровень сложности в историю про Boeing 737 MAX.

Что мы можем почерпнуть из этой истории как инженеры ПО:

  1. Исключайте единую точку отказа. Случай с MCAS является острым напоминанием о важности наличия в критических системах резервных решений. Использование в качестве ориентира единственного источника данных — в описанном случае датчика AOA — создало уязвимость, которая привела к катастрофическим последствиям. В нашей работе мы всегда должны задаваться вопросом: «Что произойдёт, если этот компонент даст сбой?»
  2. Делайте ПО и системы простыми, но не слишком простыми (принцип KISS, Keep it simple, stupid). Система MCAS стала ярким примером оверинжиниринга решения аппаратной проблемы. Вместо того чтобы устранить внутреннюю нестабильность в дизайне 737 MAX, компания Boeing решила прибегнуть к программному «исправлению», которое внесло новые уязвимости.
  3. Отсутствие предметного опыта. Многие инженеры, нанимаемые через сторонние организации, не обладают достаточным опытом в сфере аэрокосмических технологий и критических к безопасности систем. Это привело к проблемам в коммуникации и ошибкам, которые потребовали неоднократных корректировок.
  4. Слабое тестирование. Несмотря на обширное тестирование, фатальные сбои в MCAS не были обнаружены, пока самолёты не поступали на обслуживание. Это поднимает важные вопросы об адекватности текущего тестирования и практик симуляции, особенно для систем, в которых реальные условия сложно воссоздать полноценно.

Что мы, как программные инженеры, можем сделать для решения перечисленных проблем? Вот некоторые мысли по этому поводу:

  • Реализовать подобающую обработку ошибок. Проектируйте свои системы с учётом того, что их компоненты будут давать сбой. Реализуйте резервные механизмы, перекрёстные проверки и предохранительные меры.
  • Делать акцент на операторах. Делайте так, чтобы ваши системы отчётливо взаимодействовали с их пользователями, особенно в отношении их текущего состояния и любых автоматизированных действий. Предоставляйте операторам информацию и средства управления, нужные им для принятия взвешенных решений и в случае необходимости переопределения поведения автоматизированных систем.
  • Ставить в приоритет интеграционное тестирование. Несмотря на важность модульных тестов, их недостаточно. Не пожалейте времени и средств на всеобъемлющее интеграционное тестирование всей системы. Проверяйте пограничные случаи и состояния отказа.
  • Развивать культуру открытого взаимодействия. Создайте среду, в которой люди смогут безбоязненно высказывать свои беспокойства, а аварийные ситуации будут рассматриваться как ценные уроки, а не что-то постыдное, что хочется поскорее замять.
  • Отстаивать выделение необходимых ресурсов. Как инженеры ПО, мы запрашиваем те или иные ресурсы для подобающего выполнения своей работы. Это может подразумевать несогласие с нереалистичными дедлайнами, с выделением недостаточного времени на тестирование или с сокращением расходов, которое может поставить под угрозу безопасность [5].

▍ Ссылки


[1] “How the Boeing 737 Max disaster looks to a software developer”, Gregory Travis, IEEE Spectrum, 2019.
[2] “Killer software: 4 lessons from the deadly 737 MAX crashes”, Matt Hamblen.
[3] “Eight lines of code could have saved 346 lives in Boeing 737 MAX crashes, expert says.” Matt Hamblen
[4] “Boeing’s 737 Max Software Outsourced to $9-an-Hour Engineers“, Bloomberg, 2019.
[5] “The Boeing 737 MAX: Lessons for Engineering Ethics”, Herket J. et al., Sci Eng Ethics. 2020.

Видео


Telegram-канал со скидками, розыгрышами призов и новостями IT ?

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


  1. apro
    28.07.2024 09:22
    +14

    когда лётчик пытается запросить от базы освобождение ресурсов

    Серьезно, "driver" теперь как летчик переводят?


    1. lisisty
      28.07.2024 09:22
      +4

      теперь вообще на транслит исправили, не смогли в английский. Ну "водитель" же


      1. Count_s
        28.07.2024 09:22
        +26

        Гуртовщик. А правильнее конечно «Привод»


        1. Bright_Translate Автор
          28.07.2024 09:22

          Благодарю за конструктивный комментарий. Действительно неверно по контексту истолковал.


  1. fo_otman
    28.07.2024 09:22
    +20

    Кейс №1. В 1996м году не было валюты "евро".


  1. engin
    28.07.2024 09:22
    +4

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


  1. UstasAlex
    28.07.2024 09:22
    +4

    Про Боинг, конечно, кривое проектирование ПО, которое не способно отработать одну возможную неисправность. Однако, все многократно усугубилось нежелением официально объявить о существовании самой такой систем, так как это усложнило бы сертификацию и потребовало бы дополнительного обучения пилотов (а это деньги). В руководстве по эксплуатации изначально даже не было упоминания об этой системе. И, вроде, не было возможности отключить ее. То есть у пилотов не было даже теоретической возможности исправить ситуацию.


    1. Rsa97
      28.07.2024 09:22
      +11

      Упоминание MCAS в FCOM (Flight Crew Operation Manual) было. А в FCTM (Flight Crew Training Manual) было описано более подробно.

      Отключить MCAS нельзя, но можно отключить приводы перекладки стабилизаторов. Это действие входит в ситуацию Runaway Stabilizer (самопроизвольная перекладка стабилизатора), симптомы которой и действия в ней пилоты должны знать наизусть.


      1. AlexEf
        28.07.2024 09:22
        +1

        перед второй катастрофой Б разъяснили

        про то что МКАС отключается: при включении автопилоты, при выпуске закрылок/предкрылок, при включении автомата тяги


        1. Rsa97
          28.07.2024 09:22
          +2

          Катастрофы, связанные с MCAS, были в 2018 и 2019 годах, а приведённая страница FCTM от 2017.


      1. UstasAlex
        28.07.2024 09:22
        +1

        Главная проблема в первом пункте: "Определить ситуацию".

        А про упоминание, то, например, Денис Окань, как и некоторые другие авторы, утверждает, что MCAS до первой аварии упоминался только в списке сокращений.


        1. UranusExplorer
          28.07.2024 09:22

          И тот же Окань говорит, что следования старым уже десятки лет существовавшим инструкциям (той самой "Runaway stabilizer") достаточно для того, чтобы определить и решить возникающую проблему с этим новым MCAS, и другие экипажи при появлении этой проблемы с этим вполне справились. То есть по факту пилотам про существование MCAS знать было действительно не обязательно.


      1. alexhott
        28.07.2024 09:22

        имеете ввиду "перекомпенсацию руля высоты" или что-то все же другое?


        1. Rsa97
          28.07.2024 09:22
          +1

          Нет, Runaway Stabilizer - это ситуация, описанная в FCOM. То, что выше пунктирной линии, пилоты должны знать наизусть, это "действия по памяти".


    1. AlexEf
      28.07.2024 09:22
      +2

      stabilizer runaway было описано в еще 60х годах

      но даже так то ко перед второй катастрофой Б расписали логику работы


      1. Rsa97
        28.07.2024 09:22
        +1

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


  1. ktotomskru
    28.07.2024 09:22
    +3

    С боингом ситуация немного хитрее. 737max не имеет "аппаратных" проблем, которые потребовалось решать MCAS'ом. То, что двигатели расположены дальше от крыла не делает аэродинамику какой-то не такой и плохой. Это отличный самолёт.

    Проблема в том, что управление этим самолётом (без MCAS) несколько отличалось от управления всей предыдущей 737 серией как раз из-за немного другого расположения двигателей. То есть, пилот, привыкший летать на, например, 737-800 обнаруживал, что новый самолёт откликается на управление немного иначе. И тут было два варианта: либо делать долгий (а значит дорогой) курс по "доучиванию" пилотов 737 до 737-max, либо с помощью ПО сделать так, чтобы 737-max управлялся настолько же привычно, как и предыдущие самолёты этой серии. Вот это вот и делал MCAS.


    1. Rsa97
      28.07.2024 09:22
      +2

      Проблема в том, что управление этим самолётом (без MCAS) несколько отличалось от управления всей предыдущей 737 серией

      Управление не отличалось. Другие размер и расположение двигателей приводило к тому, что при больших углах атаки обшивка двигателей создавала дополнительную подъёмную силу, увеличивающую кабрирующий момент и, соответственно, и без того большой угол атаки. Эффект проявлялся в определённом диапазоне скоростей и углов атаки. MCAS как раз должен был следить, чтобы самолёт не попадал в этот диапазон, заранее перекладывая стабилизатор на пикирование, опуская нос самолёта, соответственно уменьшая угол атаки. В нормальных режимах полёта MCAS вообще никак не влиял.
      Из FCTM:

      The MCAS only operates at extreme high speed pitch up conditions that are outside the normal operating envelope.


      1. ktotomskru
        28.07.2024 09:22

        Хм.. я вот этого дядьку слушал, а FCTM не читал. Но, кажется, что противоречий нет https://youtu.be/ue400BhW0aY?si=_IpKeMD9kHNlZb9r (первые 17 минут можно пропустить).

        В 20:30 он говорит, что разница в том, что вот в этой особенной ситуации (низкая скорость и большой угол атаки) ощущение на штурвале легче/слабее, чем на предыдущих версиях 737. В то время как в статье говорится буквально о некоей внутренней нестабильности, которую следовало бы устранить аппаратным образом.


  1. djslava11
    28.07.2024 09:22

    А потому что не надо запускать 16 битную Сегу в космос ))


    1. UranusExplorer
      28.07.2024 09:22
      +4

      А сколькибитную надо?


      1. djslava11
        28.07.2024 09:22

        Теоретически, 128


        1. UranusExplorer
          28.07.2024 09:22
          +1

          а зачем?


          1. djslava11
            28.07.2024 09:22

            Чтобы не столкнуться с числовым лимитом. Но им виднее...


            1. UranusExplorer
              28.07.2024 09:22
              +5

              Разрядность процессора и шины памяти не ограничивает максимальную разрядность переменных в памяти с которыми вы можете работать. Вы даже на 8-битном процессоре можете ворочать 128-битными числами при должном подходе, правда медленно получится. А ещё часто бывает, например, что у 16-битного процессора есть 32-битные регистры, и так далее.


            1. kekoz
              28.07.2024 09:22

              Парень, поинтересуйся на досуге хотя бы характеристиками “Apollo Guidance Computer.” Это бортовой компьютер, который астронавтов на Луну доставлял. И мне кажется, что ты либо не поверишь, либо охренеешь :) Ну, если ты, конечно, не из числа убеждённых сторонников версии, что Луна и астронавты — продукт Голливуда.


  1. shares-caisson
    28.07.2024 09:22
    +9

    Ещё не читая ждал один и тот же набор набивших оскомину кейсов: Ариана, Therac, Боинг. И набор советов: тестируйте по, будьте внимательны, какую-то там культуру отстаивайте (как будто инженер "за $9 в час" из далёкой страны имеет какое-то влияние на культуру стомиллиардной американской монополии, лол).

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


    1. plFlok
      28.07.2024 09:22

      набивших оскомину кейсов

      и Therac-25


    1. ren_hoek
      28.07.2024 09:22

      И Patriot.


  1. vvbob
    28.07.2024 09:22

    Вместо того чтобы устранить внутреннюю нестабильность в дизайне 737 MAX, компания Boeing решила прибегнуть к программному «исправлению», которое внесло новые уязвимости.

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

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

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


    1. Rsa97
      28.07.2024 09:22

      Там проблема была не в тяге, а в подъёмной силе от обтекателя двигателя. Двигатель стал крупнее (больше площадь обтекателя) и больше вынесен вперёд (больше момент силы). В результате дополнительная подъёмная сила на больших скоростях и углах атаки вызывала излишний кабрирующий момент и могла привести к неконтролируемому росту угла атаки с последующим срывом потока и сваливанием.


  1. rukhi7
    28.07.2024 09:22

    Например, в мире аэрокосмонавтики ставки невероятно высоки, и программные сбои могут вести к катастрофическим последствиям.

    А если резистор или конденсатор впаять не того номинала или того пуще их перепутать, не кондицию пропустить сбоя не будет что-ли? Ставки высоки только для программных сбоев, другие ошибки не ведут, что ли к катастрофическим последствиям в мире аэрокосмонавтики?


    1. plFlok
      28.07.2024 09:22

      того пуще их перепутать

      Перепутали провода


    1. ren_hoek
      28.07.2024 09:22

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


    1. engin
      28.07.2024 09:22

      Не знаю, за какой мир Вы серчаете, но к примеру в IAI (Israel Aerospace Industries) никогда не попадает на склад ширпотреб от дядюшки Ху и ему подобных производителей. Подход к производителям компонентов сродни медицинским препаратам, которые прошли тщательный отбор и всевозможные клинические испытания на разрешение их к применению.
      Что касается сбоев софта и его дальнейшей эволюции, к примеру Маск в своих космических проектах со времен Space X взял на вооружение IDE визуального программрования на языке G (LabView), вся бортовая телеметрия и это не прихоть, а продиктованные требования, когда ошибки в транскрипции кода, априори отсутствуют, при этом разрабы все свои усилия направляют на оптимизацию применения набора тулсов.


  1. SergeyMikhaylin
    28.07.2024 09:22

    Добавлю, почти аналогичную первому случаю, ошибку в коде системы наведения ракет ЗРК "Patriot". Читал о нем давно на уже умершем сайте, но нашел на другом источнике https://tech.onliner.by/2019/10/03/zrk-patriot

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