Therac-25 pokazał, że błąd współbieżności w oprogramowaniu może skończyć się dawką promieniowania zagrażającą życiu
W latach 1985–1987 akcelerator medyczny Therac-25 uczestniczył w sześciu znanych wypadkach z bardzo dużymi przedawkowaniami promieniowania. Nie był to jeden prosty bug. Analiza Nancy Leveson i Clarka Turnera opisała kilka defektów oprogramowania, w tym race conditions zależne od bardzo szybkiej sekwencji działań operatora, a także brak wystarczających sprzętowych blokad bezpieczeństwa i słabe praktyki inżynierii systemowej. Przypadek stał się klasyką software safety, bo pokazał, że „komputer kontroluje urządzenie” nie może zastąpić niezależnych warstw ochrony.
Maszyna ufała programowi bardziej niż wcześniejsze modele
Starsze urządzenia Therac wykorzystywały więcej sprzętowych interlocków, które fizycznie uniemożliwiały pewne niebezpieczne konfiguracje. Therac-25 przeniósł część odpowiedzialności do software’u. To może zmniejszać koszt i zwiększać elastyczność, ale jednocześnie sprawia, że pojedynczy błąd logiczny może ominąć ochronę, która wcześniej istniała niezależnie od programu.
Race condition zależał od tempa operatora
W jednym z najbardziej znanych scenariuszy operator mógł szybko poprawić wcześniej wpisany tryb zabiegu. Oprogramowanie aktualizowało różne struktury stanu w różnym czasie. Jeśli sekwencja klawiszy następowała w odpowiednim oknie, część programu uważała, że konfiguracja jest bezpieczna, choć sprzęt znajdował się w innym stanie. Błąd zależał więc od kolejności i czasu zdarzeń, nie tylko od ich wartości.
Nie wszystkie wypadki miały ten sam mechanizm
Leveson i Turner opisali także inny defekt związany z jednobajtowym licznikiem, który co 256 iteracji przyjmował wartość zero. To ważne, bo Therac-25 jest czasem błędnie streszczany jako „jeden race condition zabił ludzi”. W rzeczywistości system miał wiele słabości, a powtarzające się incydenty ujawniały problem procesu bezpieczeństwa, diagnostyki i analizy zagrożeń.
Komunikaty błędów nie pomagały operatorom
Interfejs wyświetlał enigmatyczne kody i pozwalał wznawiać działanie po części błędów. Operatorzy wcześniej widywali podobne komunikaty bez dramatycznych konsekwencji, więc nie mieli podstaw, by interpretować je jako sygnał potencjalnie śmiertelnego stanu. To przykład alarm fatigue: jeśli system często generuje niejasne ostrzeżenia, ludzie uczą się je ignorować.
Producent zbyt długo szukał awarii sprzętowej
Pierwsze zgłoszenia były trudne do odtworzenia i początkowo nie prowadziły do jednoznacznego znalezienia defektu. W systemach współbieżnych problem może znikać przy zwykłym debugowaniu, bo zmiana tempa wykonania usuwa race condition. Brak pełnych logów dodatkowo utrudniał ustalenie, co dokładnie stało się podczas zabiegu.
Bezpieczeństwo nie może zależeć od jednej warstwy
Największa lekcja Therac-25 nie brzmi „nie używaj software’u w medycynie”. Brzmi: projektuj system tak, aby pojedynczy błąd nie prowadził bezpośrednio do katastrofy. Niezależne interlocki, walidacja stanu, ograniczenia dawki, dobre logowanie i testy scenariuszy współbieżnych powinny nakładać się na siebie. Wiele późniejszych standardów bezpieczeństwa medycznego i przemysłowego formalizuje tę filozofię: nie wystarczy wykazać, że nominalna funkcja działa. Trzeba prowadzić hazard analysis, zarządzać zmianami, śledzić wymagania do testów oraz wykazać, że system przechodzi do stanu bezpiecznego również przy awarii komponentu.
Dlaczego certyfikacja systemu wymaga analizy hazardów, nie tylko testów funkcjonalnych
Test funkcjonalny może potwierdzić, że operator wpisuje dawkę, urządzenie ustawia tryb i naświetlanie rozpoczyna się poprawnie. Nie odpowiada jednak na pytanie, co stanie się przy bardzo szybkiej edycji danych, awarii komunikacji, niespójnym stanie zmiennych albo jednoczesnym wystąpieniu dwóch błędów. W safety engineering zaczyna się od hazardu — np. „pacjent może otrzymać niebezpiecznie dużą dawkę” — a następnie szuka wszystkich ścieżek, które mogą do niego prowadzić. Dopiero potem projektuje się niezależne bariery i testy. Therac-25 stał się klasycznym materiałem dydaktycznym właśnie dlatego, że pokazał ograniczenie myślenia „software przeszedł testy, więc jest bezpieczny”. Program może prawidłowo obsługiwać tysiące zwykłych przypadków i nadal mieć bardzo wąską ścieżkę do katastrofalnego stanu. W systemach medycznych ryzyko mierzy się skutkiem i prawdopodobieństwem, nie procentem testów zakończonych sukcesem.