На днях стала впервые известна обширная статистика по применению в США роботов-хирургов. Оказалось, что в период с 2000 по 2013 годы 144 операции с их использованием закончились смертью пациента, причем несколько из них были вызваны программными ошибками. Конечно, то, что роботы стали убивать людей вовсе не значит, что до сих пор с этим не справлялись сами люди: недобросовестные хирурги или медсестры. Но неуклонно растущая компьютеризация всего и вся делает вероятность возникновения таких ошибок все выше, и уже сейчас от этого становится немного не по себе.

На самом деле, не все погибшие находятся на совести роботов. 10 случаев из 144 пришлось на ошибки живых операторов, и лишь три случая стали следствием системных сбоев и самопроизвольных движений роботов во время операции (программные ошибки в строгом смысле этого слова). В ряде случаев оперировались довольно тяжелые пациенты, для которых определенная вероятность погибнуть от осложнений имелась в любом случае, вне зависимости от того, чьи руки его оперировали. Наконец, не секрет, что ошибки более многочисленных хирургов-людей приводят к куда большему количеству летальных исходов. По данным соответствующего исследования только за 1990-2010 годы грубые ошибки — в том числе, оперирование не того органа или даже не того пациента — привели к смерти 660 лиц, подвергшихся хирургическому воздействию в США.

И все же программные ошибки именно в медицинском оборудовании получают наибольшую известность. Классическим примером одного из типов ошибок стала история аппарата Therac-25, который использовался в 80-х для лучевой терапии. 

Эти аппараты были, с современной точки зрения, большой программной экзотикой — они имели многозадачную операционную систему, написанную на ассемблере, хотя для решения подобной задачи было бы правильнее воспользоваться языками более высокого уровня, ведь трудоемкость подобной разработки на низкоуровневом языке самоочевидна. И, как это часто бывает, одна критическая ошибка прошла незамеченной. Работа системы зависела от того, в каком именно порядке выполняются части кода, что приводило к классической ошибке состояния гонки. Если в многопоточной системе один поток выполняет над общей переменной x операцию x = x + 3, а второй поток — операцию x = x + 5, то каждый из потоков считывает x из памяти, увеличивает x, а потом записывает x в память. В зависимости от взаимного порядка выполнения потоками каждой из этих трех подопераций итоговое значение переменной x может быть больше исходного на 3, 5 или даже 8.

В случае Therac-25 аппарат имел три рабочих режима. В первом (облучение разогнанными электронами) электронная пушка напрямую облучала пациента, при втором (рентгеновская терапия) сперва обстреливала вольфрамовую мишень, а пациент получал рентгеновские лучи, проходящие через рассеиватель. В третьем режиме (прицеливания) стальная заглушка не давала установке облучать пациента, лишь регулируя ее нацеливание на нужную часть тела. Из-за того, что потоки допускали состояние гонки между параллельными процессами, управляющая программа и обработчики клавиатуры могли в разном порядке получать доступ к вращающемуся диску с магнитами, который ставил заглушку перед электронной пушкой. В итоге аппарат облучал человека в первом (самом жестком) режиме, а сам в это время выводил на экран данные от третьего режима, сообщая медпресоналу, что пациент получил нулевую дозу. Возвращаясь к аналогии выше, гонка состояний повышала итоговое значение переменной на 5, а в память записывала его равным исходному. Из-за этого медсестра снова повторяла процедуру, что и вело к переоблучению. Всего аппарат дал не меньше шести случаев избыточного облучения его больных, при этом как минимум в двух случаях пациенты вскоре умерли. Смертей могло бы и не быть, если бы после первого же случая переоблучения медики жестко потребовали бы от производителя детального расследования причин сбоев. Удивительно, что случай с Therac-25 не единичный. В 1991-м году в Испании аппарат Sagitar-35 за 10 дней переоблучил десятки пациентов, трое из которых вскоре умерли. В 2001 году в Панама-Сити другой аппарат производства Multidata Systems International неправильно рассчитал дозы облучения 28 человек, что в нескольких случаях привело к смерти. Правда, в последней ошибке была и доля вины медработников. Программа рассчитывала дозировку, исходя из определенного порядка расположения щитов вокруг пациента. Персонал решил эту раскладку изменить, что позволило сильно сократить время подготовки к операции. Однако системы автоматического расчета необходимой дозы не предусматривали такого «улучшенного» расположения щитов и в итоге назначали ошибочную дозу.

Впрочем, как известно, роботы могут не только лечить людей: ASDReports недавно выпустило прогноз, согласно которому рынок наземных боевых роботов (в основном, телеуправляемых) к 2020 году достигнет 8,3 миллиарда долларов. Их первые жертвы появились еще во время войны на Фолклендах, когда была применена автономная роботизированная зенитная установка Oerlikon GDF. В 2007 году ее модернизированный вариант на учениях в ЮАР внезапно — по так и не выясненной до конца причине — начал стрельбу. За 0,125 секунды он убил 9 и ранил 14 человек из персонала находившихся рядом аналогичных установок. Предполагаемой причиной инцидента стал сбой ПО, однако проверить это — в силу его закрытости, частой в ВПК — весьма затруднительно.

Чуть яснее ситуация с программной ошибкой комплекса Patriot, приведшей к инциденту, который произошел на американской базе в Дахране 25 февраля 1991 года. Его причиной стало округление секунд, вызвавшее сбой счета времени в работе системных часов комплекса. При разработке системы предполагалось, что Patriot будет постоянно переезжать вслед за наступающими войсками, и среднее время между перезагрузками составит считанные часы. Однако в Дахане комплекс стоял на месте, в результате чего незначительное округление системного времени привело к отставанию системных часов на 0,34 секунды. В итоге Patriot не смог перехватить иракскую ракету «Скад», и та успешно поразила расположение американцев, 28 человек погибли, две сотни было ранено. И все это несмотря на то, что за две недели до инцидента израильтяне заметили это слабое место купленных ими Patriot и уже посоветовали американцам перезагружать свои ЗРК раз в несколько часов.От сбоя в расчете текущего времени в феврале 2007 года пострадали и шесть истребителей F-22. Когда они пытались перелететь с Гавайев в Японию, то после пересечения линии перемены дат их ПО испытало множественные сбои, детали которых пока засекречены. Известно лишь, что системы навигации и связи полностью отключились, и самолеты были вынуждены возвращаться на базу, следуя за своими самолетами-заправщиками. Случись это ночью или в плохую погоду они бы их просто не разглядели, и имели все шансы потеряться над океаном, не долетев до аэродромов.Стоит отметить, что в оборонной сфере ПО чрезвычайно сложно полностью проверить на отсутствие багов. Поэтому, например F-35B в июле этого года принимают на вооружение Корпуса морской пехоты США с восемью неисправленными программными ошибками, которые относятся к второстепенным в мирное время системам (сенсоры наблюдении за землей и так далее) — цикл их исправления затянулся бы на значительное время, сорвав сроки поступления на вооружения. Конечно, эти ошибки серьезно ограничивают боевое применение самолетов, которые не могут объединять потоки данных разнородных сенсоров, а значит и корректно наводить оружие. Так что применять F-35 в реальном бою пока все равно рано (полную готовность обещают лишь в 2017 году).Учитывая, что ПО истребителя включает восемь миллионов строк кода, надеяться, что в нем не осталось ни одной другой ошибки, невозможно: это ненормально низкий уровень даже по меркам крайне отработанных продуктов. Очевидно, речь идет только об обнаруженных неисправленных ошибках. И дальнейшее выявление новых будет идти само собой, как во время вышеупомянутого полета F-22.Впрочем, роботы, расстреливающие военнослужащих из орудийных стволов или неправильно считающие время и дату, — угроза довольно скромная. Гораздо опаснее могут быть ошибочные действия более продвинутых роботизированных систем. 26 сентября 1983 года принятая на вооружения за год до этого система «Око» сообщила советскому командованию, что американская сторона запустила межконтинентальные баллистические ракеты Minuteman, что требовало немедленной ответной ядерной атаки.Спутники «Ока» летали по орбите типа «Молния», позволявшей им фиксировать инфракрасное излучение от взлетающих ракет на фоне края земного диска. Это позволяло не путать излучение ракет с отражением солнечного излучения от нижней кромки облаков. Но 28 сентября взаимное расположении Солнца, Земли и спутников оказалось таково, что нагрев части облаков у края диска все же достиг критической величины и космический эшелон системы предупреждения о ракетном нападении (СПРН, то самое «Око») принял его за пуск пяти американских ракет. В теории, СПРН была оснащена компьютером, который позволял отфильтровывать отражении солнечного ИК-излучения от облаков и не смешивать его реальными запусками. Увы, в тот раз специализированное программное обеспечение не справилось с таким отделением шумов от сигнала. Детали сбоя по понятным причинам засекречены. Однако полковник Станислав Петров, присутствовавший в тот день на командном пункте «Серпухов-15», уже после распада СССР в интервью сообщал, что после этого инцидента программа, отвечавшая за фильтрацию данных со спутников была переписана. Так из-за некорректной работы одной программы весь мир на шесть минут оказался на пороге ядерной войны.К счастью, отражения от облаков, принятые за реальные пуски, были малочисленны, а Петров посчитал, что США вряд начнут ядерную войну с СССР с запуска всего пяти ракет — ведь они явно не смогли бы подорвать советский атомный потенциал. Поэтому он решил подождать данных с наземных радаров и других систем оповещения, не подтвердивших ложных данных «Ока».

В настоящее время ПО играет критическую роль в гораздо большем количестве областей, чем во времена, когда оно едва не начало последнюю войну. Поэтому полностью охватить все случаи багов, имевших катастрофические последствия, практически невозможно. Недавнее «зависание» космического парусника LightSail-1 (переполнения файла с логом системы) — типичный пример. Установка на аппарат более производительного оборудования привело к росту объема файлов лога, что невозможно было предусмотреть во времена, когда начиналась отработка ПО (ошибка «640 килобайт хватит на всех»).

Аналогичным образом не смогли выявить ошибку и специалисты NASA перед отправкой к Венере в 1962 году своего первого межпланетного аппарата — Mariner 1. Сработала та часть кода, которая отвечала за подавление ложных команд с принимающей антенны. Она должна была активироваться лишь при очень плохом сигнале, однако тот тип помех, с которыми антенна столкнулась при запуске в наземных условиях, не отрабатывался. В итоге, когда ПО должно было заблокировать шум с антенны, оно не справилось с задачей: перед пуском при ручном переводе символа макрона (над R̄n) в спецификации программы управления специалист, выполнявший задачу, пропустил надчеркивание над символом. Попытки выполнять «команды», порожденные шумом, привели ракету-носитель для Mariner 1 к гибели на пятой минуте полета.Конечно, далеко не всегда вина лежит на необычных условиях работы кода. Например, первый запуск европейской ракеты Ariane 5  закончился только по причине избыточного стремления ее разработчиков к унификации стандартных модулей. Одна из систем инерциальной навигации ракеты без изменений досталась ей от Ariane 4, которая, однако, имела иные допустимые углы подъема на орбиту. Когда Ariane 5 превысила значение, допустимое для предшественника, система инерциальной навигации посчитала, что произошла системная ошибка, и запустила диагностическую программу. Обычно та работает только на земле, но по каким-то причинам ее код предусматривал отключение лишь через 50 секунд полета. Именно в этот момент данные программы диагностики попали в бортовой компьютер и привели его к серии хаотических перемещений сопел двигателей первой ступени, спровоцировавших автоподрыв ракеты.Здесь, как и во многих других случаях, напрашивается вывод: роботы, ракеты и самолеты не ошибаются. Реальными причинами сбоев ПО чаще всего являются не столько необычные условия его работы, сколько решения программирующих все эти системы людей. Как бы не пугала нас временами железная поступь прогресса, самыми страшными ее проявлениями мы обязаны природе самого человека: человеку (и написанным им программам) свойственно ошибаться. Быть может, если программисты будут почаще вспоминать об этом, у них получится аккуратнее относится к своей работе. Учитывая, что в современном мире от них зависит, скажем, работа современной версии «Ока», жизни большинства из нас зависят от этой аккуратности.

Борис Александров

Нашли опечатку? Выделите фрагмент и нажмите Ctrl+Enter.