25 апреля 2019 в 8:00
Автор: Ян Альшевский

Фатальные ошибки в программном коде: история аппарата лучевой терапии Therac-25, убившего людей

Автор: Ян Альшевский

В 1984 году на экраны вышел фильм «Терминатор» с Арнольдом Шварценеггером в главной роли. Персонаж стал посланником злобного искусственного интеллекта, который стремится уничтожить все живое на Земле или подчинить его своей воле. С чего все началось? Вероятно, с ошибки программистов, которые в коде не там поставили запятую и предоставили Skynet слишком много свободы.

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

Содержание

Аппарат для лечения агрессивных форм рака

Лучевую терапию применяют давно и достаточно успешно, инженеры и медики совершенствуют технологии и оборудование, которое призвано помочь в борьбе со злокачественными образованиями. То и дело появляются революционные решения — сегодня они могут казаться устаревшими, но 30—40 лет назад считались прорывом.

Врач Уильям Коли рядом с одним из первых пациентов и одной из первых подобных машин

В конце 1970-х годов канадское правительство инициировало разработку полностью компьютеризированной системы Therac-25 — аппарата лучевой терапии для лечения агрессивных форм рака, более эффективного с медицинской и экономической точки зрения, нежели предшественники Therac-6 и Therac-20.

Медицинский линейный ускоритель мог работать в двух режимах: с небольшой интенсивностью излучения и высокой (это упрощенное описание) в зависимости от того, на какой глубине в тканях находился очаг. Одним из ключевых отличий Therac-25 от Therac-20 стал переход на полностью программное управление.

Вероятно, это и есть тот самый Therac-25, однако в сети можно найти разные изображения
VT100, который (опять же — вероятно) использовался в качестве терминала для доступа к функциям Therac-25

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

Оптимизация разработки

Чтобы оптимизировать разработку, создатели Therac-25 использовали старый код — написанный для предыдущих «тераков». Тот, в свою очередь, по данным ряда источников, был написан программистом-самоучкой, который не имел профильного образования. Возможно, по этой причине он не стал сопровождать код комментариями — разобраться в нюансах было непросто, а создавать программную платформу с нуля не захотели.

Поставки Therac-25 в медучреждения США и Канады начались в 1983 году, и первое время информации о сбоях не было. Системе было несложно пройти все инстанции и получить разрешения от регуляторов — в машине применялось уже существующее ПО, поэтому его пропустили без особых вопросов. В то время около 94% медицинского оборудования попадало на рынок именно таким образом, что упрощало, ускоряло и удешевляло вывод новых устройств. А как все это работало, вопрос другой.

Изображение носит иллюстративный характер

Для проверки степени опасности и рисков выхода системы из строя применялся Fault Tree Analysis (или «анализ дерева отказов»). В процессе определялись те самые «опасные последствия», условия, которые к ним приведут, и предпринятые шаги в этой цепочке. Затем оценивался шанс возникновения ситуаций. Вновь подчеркнем — это упрощенное описание подхода.

Главное заключалось в том, что анализ решили не проводить, так как программное обеспечение «зарекомендовало себя как безопасное во время работы на Therac-6 и Therac-20». То, что Therac-25 значительно отличается от предыдущих поколений медицинских ускорителей, решили опустить. Компания-разработчик оценила шанс неправильной работы как почти несуществующий, а возможные ошибки в ПО проигнорировала.

Therac-6 в одной из лондонских клиник в 1975 году

Позже оказалось, что в ПО существовала уйма критических ошибок. Одну из них называют race condition. В случае с Therac-25 использовалась одна и та же переменная для двух команд, которые могли выполняться в произвольном порядке, что для описываемого аппарата неприемлемо.

К примеру, в одном из режимов при максимальной интенсивности излучения между пациентом и электронной пушкой должен был устанавливаться «рассеиватель», распределяющий поток. Машина же выполняла не ту последовательность, и на человека обрушивался мощнейший луч. Проверяющая система, в свою очередь, из-за неверной команды (которая, опять же, не проверялась дублирующими системами) неправильно оценивала уровень радиации и «стреляла» вновь.

Схема наглядно описывает то, как может работать система

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

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

Свою роль играла работа магнитов, которые позиционировали поворотный диск с «прицелами» для разных видов терапии. Если оператор вносил корректировку в мощность и тип излучения слишком быстро, машина не успевала перевести диск. Тогда шансы получить высокую дозу составляли 50 на 50. Если принять во внимание все возможные ошибки, то окажется, что Therac-25 представлял собой чуть ли не русскую рулетку с радиацией вместо пуль.

Текстовый интерфейс для ввода данных Therac-25

Начало «неприятностей»

Основные «неприятности» аппарат лучевой терапии принес в период с 1985 по 1987 год шести людям (это те, о которых есть информация). Первый смертельный исход был зафиксирован в 1986 году.

Жертвой стал пациент, проходивший девятую для него процедуру облучения. Оператор, внося команду, допустила опечатку — вместо Е (электронная терапия) она указала Х (рентгеновская терапия). Заметив это, она вернулась на пункт выше и поставила верную букву. В этот момент в системе произошла ошибка — их случались десятки в день, так что «ничего странного».

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

Снимок носит иллюстративный характер

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

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

На этот раз интерком работал и оператор услышала стоны пациента, чье лицо оказалось под ударом радиации. Спасти человека не удалось — мужчина впал в кому и умер спустя три недели после инцидента.

Третья жертва неверно написанного ПО, отсутствия тестирования и, вероятно, желания сэкономить умерла в январе 1987 года. Вновь речь шла о сбоях, ошибках в работе системы, ее перезагрузке и отчете компьютера о дозе в 7 рад, что не соответствовало действительности. Пациент жаловался на жжение в области облучения, это «как бы приняли к сведению», а спустя три месяца он умер от последствий лучевой болезни.

Изображение носит иллюстративный характер

Отрицание

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

В июне 1985 года 61-летняя женщина проходила терапию после удаления раковой опухоли в груди. После сеанса лучевой терапии с использованием аппарата Therac-25 ее плечо и рука оказались парализованы, а грудь пришлось удалить. Канадская государственная корпорация AECL, которая выступала заказчиком ускорителей, отказалась признать вину.

«Этого не может быть, ошибки и некорректная работа Therac-25 исключены. Возникновение отека — это нормально», — примерно так говорилось в их заявлении.

Второй инцидент произошел спустя примерно месяц в другом медучреждении. На этот раз под излучателем оказалась 40-летняя пациентка. Во время сеанса машина сообщила о нулевой интенсивности излучения. Оператор ставил систему на паузу и возобновлял процедуру — аппарат был направлен в область таза. Это повторилось пять раз, потому что Therac-25 продолжал выдавать одно и то же уведомление — нулевая доза.

Прибывший по вызову техник отрапортовал: «Все в порядке, неисправностей нет». Пациентку госпитализировали, а позже она умерла — причиной стало развитие рака. Но останься она живой, женщине как минимум бы потребовалась замена тазобедренного сустава, уничтоженного ускорителем.

Третий инцидент имел место в том же 1985 году. Пациентка получила шрамы, но выжила. Сперва недомогание списали на основное заболевание, возможность радиационного «овердоза» начали рассматривать лишь год спустя. Вред здоровью был нанесен, но в сравнении с другими случаями — «незначительный».

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

Снимок носит иллюстративный характер

В AECL до последнего пытались найти ошибки в «железе», практически не принимая во внимание код. В то же время, как утверждают некоторые специалисты, чтобы достичь заявленного уровня безопасности, инженерам компании пришлось бы тестировать систему на протяжении 100 тыс. лет. На деле же, по их словам, к тестированию относились спустя рукава, после внедрения исправлений софт не прогоняли через всевозможные испытания. А ведь шанс того, что что-то «сломается» после патча, достаточно велик — 50 на 50.

Наконец выяснилось, что все ошибки достались Therac-25 от Therac-20 и, вероятно, даже от Therac-6 (в котором рентгеновского режима не было вовсе). На старых системах баги никак не проявляли себя из-за аппаратных решений обеспечения безопасности. А в новой «продвинутой» системе стали очевидны — ничто не могло их «прехватить». И вот при разовой терапевтической дозе до 200 рад пациенты, как утверждают некоторые источники, получали до 20—25 тыс. рад (точечно, так как смертельная доза для всей поверхности тела в разы меньше).

Признать ошибку и остановить работу

В 1987 году американский и канадский регуляторы потребовали остановить работу всех Therac-25 (их насчитывалось чуть менее полутора десятков в США и Канаде) до выяснения обстоятельств. За полгода AECL составила план и утвердила его, внедрив аппаратные системы защиты и доработав ПО. Оставшиеся в живых жертвы и их родственники подали иски, однако все вопросы были улажены сторонами в досудебном порядке.

Остается открытым вопрос, кто тот программист-самоучка, который работал то ли на полную ставку, то ли на аутсорсе, то ли «халтурил» по вечерам? История тщательно скрывает этот момент. Может, он просто не имел опыта разработки систем, функционирующих в режиме реального времени, однако в жизни был хорошим парнем?

Ну а история Therac-25 стала уроком о том, как нельзя проектировать системы с повышенными требованиями к безопасности.

Список источников: Bugsnag, Hackaday, California Polytechnic State University, Stanford University, IEEE Computer Society, How Not To Code, ComputingCases, Wikibooks, Interesting Engineering, Virginia Tech.

геймерский, CPU AMD Ryzen 3 1200 3100 МГц, RAM DDR4 8 ГБ, HDD+SSD 500+120 ГБ, графика: NVIDIA GeForce GTX 1650 4 ГБ, БП 500 Вт
домашний/офисный, CPU Intel Core i5 8500B 3000 МГц, RAM DDR4 SO-DIMM 8 ГБ, SSD 256 ГБ, графика: встроенная в процессор

Читайте также:

Наш канал в Telegram. Присоединяйтесь!

Быстрая связь с редакцией: читайте паблик-чат Onliner и пишите нам в Viber!

Читайте нас в Дзене

Перепечатка текста и фотографий Onliner без разрешения редакции запрещена. nak@onliner.by