Therac-25: błąd w kodzie, który zabijał pacjentów

W połowie lat 80. maszyna do radioterapii Therac-25 miała leczyć nowotwory. Zamiast tego, przez błąd w kodzie, kilku pacjentów otrzymało dawki promieniowania sto razy większe niż zamierzone. To jedna z najbardziej przerażających historii w dziejach informatyki – i lekcja, która zmieniła sposób, w jaki piszemy oprogramowanie odpowiedzialne za ludzkie życie.

Maszyna, która miała być przełomem

Therac-25 był flagowym produktem kanadyjskiej firmy Atomic Energy of Canada Limited (AECL) – akceleratorem liniowym do radioterapii, wprowadzonym na rynek w 1982 roku. W porównaniu do wcześniejszych modeli, Therac-6 i Therac-20, nowa maszyna była w pełni sterowana komputerowo. To był ogromny krok naprzód: operator wpisywał parametry na klawiaturze, a komputer sterował wiązką promieniowania, jej mocą i trybem pracy.

Problem w tym, że wraz z cyfryzacją zniknęło coś, co wcześniej chroniło pacjentów fizycznie. W starszych modelach niezależne od oprogramowania blokady mechaniczne uniemożliwiały wystrzelenie wysokoenergetycznej wiązki elektronów bez odpowiedniej osłony. W Therac-25 inżynierowie uznali, że skoro oprogramowanie i tak steruje wszystkim, sprzętowe zabezpieczenia są zbędne. Cała odpowiedzialność za bezpieczeństwo pacjenta spadła na kilka tysięcy linijek kodu.

Anatomia śmiercionośnego błędu

Między 1985 a 1987 rokiem doszło do co najmniej sześciu udokumentowanych przypadków, w których pacjenci otrzymali dawki promieniowania nawet stukrotnie wyższe od zaleconych. Skutki bywały tragiczne – oparzenia, trwałe uszkodzenia nerwów, a w kilku przypadkach śmierć.

Przyczyną był klasyczny race condition – błąd współbieżności, który ujawniał się tylko wtedy, gdy doświadczony operator wpisywał dane na tyle szybko, że zdążył poprawić parametr leczenia (np. zmienić tryb z wysokoenergetycznej wiązki elektronów na tryb rentgenowski) w ciągu około ośmiu sekund. W takiej sytuacji część procedury sprawdzającej ustawienia nie zdążała się wykonać, a maszyna wystrzeliwała pełną moc wiązki elektronów bez odpowiedniego filtra rozpraszającego. Operator widział jedynie enigmatyczny komunikat Malfunction 54 i informację, że dawka mogła być zbyt niska lub zbyt wysoka – bez żadnej wskazówki, że właśnie doszło do przedawkowania.

Do tego dochodził drugi, równie podstępny błąd: przepełnienie licznika zmiennej używanej do sprawdzania, czy operator zakończył wprowadzanie danych. Przy określonej sekwencji działań licznik ten cyklicznie wracał do wartości, która błędnie sugerowała komputerowi, że wszystko jest gotowe do strzału.

Dlaczego nikt nie chciał uwierzyć

Najbardziej niepokojącym elementem tej historii nie był sam błąd, lecz reakcja producenta. Gdy szpitale zgłaszały podejrzenie przedawkowania, AECL konsekwentnie odpowiadało, że awaria sprzętu jest niemożliwa, a przyczyną muszą być błędy operatorów lub inne czynniki zewnętrzne. Firma nie potrafiła nawet odtworzyć usterki we własnym laboratorium, ponieważ wymagała ona bardzo konkretnej, nietypowej sekwencji naciśnięć klawiszy.

Dopiero uporczywość fizyków medycznych z kilku ośrodków, a później szczegółowe śledztwo prowadzone przez badaczkę inżynierii oprogramowania Nancy Leveson, pozwoliły odtworzyć dokładny mechanizm błędu. Leveson pokazała, że problem nie leżał w jednej literówce, lecz w całej filozofii projektowania – braku niezależnych zabezpieczeń, słabej kulturze testowania i przekonaniu, że oprogramowanie, które działało w poprzednich wersjach, jest z definicji bezpieczne.

Lekcja, która zmieniła inżynierię oprogramowania

Sprawa Therac-25 trafiła do podręczników akademickich i stała się fundamentem współczesnego podejścia do bezpieczeństwa systemów krytycznych. Jej konsekwencje odczuwamy do dziś:

  • Powstały rygorystyczne normy dla oprogramowania medycznego, takie jak IEC 62304, wymagające formalnej analizy ryzyka na każdym etapie rozwoju.
  • Upowszechniła się zasada obrony w głąb (defense in depth) – system krytyczny nigdy nie powinien polegać wyłącznie na jednej warstwie zabezpieczeń, zwłaszcza jeśli tą warstwą jest tylko kod.
  • Testowanie współbieżności i przypadków brzegowych stało się standardowym elementem procesu wytwarzania oprogramowania, a nie opcjonalnym dodatkiem na koniec projektu.
  • Przypadek ten pokazał, że komunikaty błędów muszą być zrozumiałe i informować operatora, co faktycznie się stało – niejasny kod błędu może kosztować życie.

Co ta historia mówi Twojej firmie

Większość firm nie tworzy oprogramowania sterującego akceleratorami medycznymi, ale mechanizm, który zabił pacjentów Therac-25, jest zaskakująco uniwersalny: usunięcie zabezpieczeń w imię wygody, poleganie wyłącznie na jednej warstwie ochrony i ignorowanie sygnałów ostrzegawczych, dopóki nie staną się kryzysem.

W codziennej pracy IT MŚP przekłada się to na konkretne nawyki – regularne audyty konfiguracji i kodu, testowanie zmian przed wdrożeniem na produkcję, niezależne kopie zapasowe zamiast polegania na jednym systemie oraz jasne procedury reagowania, gdy coś działa nietypowo. To właśnie dlatego audyty IT i uporządkowane procesy DevOps nie są biurokratycznym dodatkiem, lecz realną ochroną przed kosztownymi, a czasem nieodwracalnymi błędami.

Wybrane udokumentowane przypadki przedawkowania przez Therac-25
DataMiejsceSkutek
Czerwiec 1985Marietta, Georgia, USAPoważne oparzenia i trwałe uszkodzenie tkanek
Lipiec 1985Hamilton, Ontario, KanadaCiężkie obrażenia, trwała niepełnosprawność
Grudzień 1985Yakima, Washington, USAPoważne oparzenia skóry i tkanek głębokich
Marzec 1986Tyler, Texas, USAŚmierć pacjenta wskutek przedawkowania
Kwiecień 1986Tyler, Texas, USAŚmierć pacjenta kilka tygodni po naświetlaniu
Styczeń 1987Yakima, Washington, USAŚmierć pacjenta wskutek przedawkowania

Nie czekaj na własny Malfunction 54

Twoja firma może nie tworzy oprogramowania medycznego, ale każdy system krytyczny dla działania biznesu zasługuje na solidne zabezpieczenia i regularną kontrolę. Sprawdźmy razem, czy Twoja infrastruktura IT nie ma ukrytych luk, które ujawnią się dopiero w najgorszym możliwym momencie.

Zamów audyt IT Bezpłatna konsultacja