W dzisiejszym wpisie omawiam najbardziej znany przypadek błędu systemu safety-critical z branży medycznej prowadzący do ciężkich obrażeń i śmierci pacjentów. Został on wnikliwie przeanalizowany teraz służy jako case study w różnego rodzaju materiałach o systemach safety.
Co to Therac-25 i jaki był z nim problem?
Therac-25 to urządzenie do radioterapii stosowane w latach 80-tych w jedenastu szpitalach w USA i Kanadzie. W latach 1985-87 odnotowano sześć przypadków podania pacjentowi stukrotnie większej dawki promieniowania niż ustawiona przez lekarza powodując poważne obrażenia i śmierć pacjentów.
Radioterapia jest wykorzystywana w leczeniu nowotworów i polega na zabijaniu komórek rakowych przy pomocy promieniowania jonizującego. Terapia działa punktowo, ale zawsze ucierpi również trochę zdrowych komórek. Poprawnie przeprowadzony zabieg radioterapii jest dla pacjenta bezbolesny. Therac-25 był w użyciu od 1982 roku i zdecydowaną większość zabiegów przeprowadzał poprawnie. Jednak we wspomnianych sześciu przypadkach pacjenci od razu czuli ból i gorąco. Próbowali choćby uciekać z zasięgu jego działania.
Od razu nasuwa się pytanie – skoro pierwsze przypadki awarii odnotowano w 85 roku, dlaczego z wycofaniem tego modelu czekano kolejne dwa lata? Otóż już po pierwszym takim incydencie lekarze podejrzewali błąd w logice urządzenia. Producent jednak upierał się, iż nie jest to możliwe i jako możliwe przyczyny wskazywał problemy mechaniczne i elektryczne. W międzyczasie odnotowywano kolejne wypadki, na które odpowiedzą były zmiany hardware’owe. Niestety nie przynosiły one spodziewanych rezultatów. Ostatecznie pracownicy jednego ze szpitali, w którym doszło do dwóch wypadków odkryli sposób reprodukcji błędu i ostatecznie udowodnili błąd po stronie programu. Therac-25 został uznany za wadliwy i wycofany z użycia.
Jak doszło do podania wysokiej dawki promieniowania?
Therac-25 mógł działać w trzech trybach:
- Electron mode – wiązka małej mocy pokrywająca większy obszar
- X-Ray mode – wiązka dużej mocy działająca na małym obszarze. Wygenerowana wiązka przechodziła przez dodatkowe filtry zmniejszające jej moc i zawężające obszar działania.
- Light mode – brak promieniowania. Urządzenie emitowało jedynie światło pomagające skierować głowicę na odpowiednie miejsce.
Gdy wybrano X-ray mode – filtry ustawiały się na drodze wiązki przez około 8 sekund. o ile w tym czasie operator zmienił tryb na electron mode, wiązka dużej mocy nie była podawana na filtr i działała bezpośrednio na ciało pacjenta. Możliwa była również druga sekwencja umożliwiająca podanie zbyt dużej dawki promieniowania występująca podczas przełączania między X-ray mode a light mode.
Aby wysłać komendy powodujące błędne zachowanie, operator musiał osiągnąć dużą wprawę w posługiwaniu się interfejsem użytkownika. Większość operatorów spisywała komendy wolniej i dlatego problem pojawiał się rzadko i dopiero po kilku latach działania sprzętu.
Problemy z kodem
Program działał na komputerze PDP-11 i składał się z wielu niezależnie działających wątków i własnego schedulera. Został napisany w całości w asemblerze. Kod napisany w całości przez jedną osobę, która nie miała dużego doświadczenia z systemami współbieżnymi. Podczas dochodzenia w sprawie wypadków z udziałem Therac-25 kod został poddany szczegółowej analizie i okazało się, iż posiadał między innymi następujące błędy:
- Wątki wykorzystywały pamięć współdzieloną bez żadnych mechanizmów synchronizacji powodując możliwe wyścigi. Najważniejszym przypadkiem wyścigów było używanie tej samej zmiennej do analizy komend wydawanych przez operatora i śledzenia pozycji głowicy.
- Podczas obliczania mocy wiązki możliwe było dzielenie przez 0 powodujące ustawienie maksymalnej wartości mocy.
- Flaga informująca o niewłaściwej pozycji filtrów była aktualizowana poprzez przypisanie wartości, tylko inkrementację. Nie obsługiwano poprawnie przepełnienia 8-bitowej zmiennej umożliwiając przegapienie flagi przy wartości 0.
Therac-25 był trzecim urządzeniem z serii. Poprzednie modele – Therac-6 i Therac-20 mogły być zarówno sterowane manualnie przez operatora, jak i przez program. Aby uniemożliwić ryzykowne operacje posiadały zabezpieczenia sprzętowe np. bezpieczniki wyłączające układ w przypadku generowania wiązki dużej mocy zanim filtry będą na swoim miejscu. Baza kodu dla dwóch poprzednich wersji była wykorzystana również w Therac-25. Błędy w kodzie istniały już wcześniej, ale zabezpieczenia sprzętowe nie pozwoliły im na spowodowanie szkód.
Przyczyny błędów
Wszystkie incydenty z udziałem Therac-25 zostały dokładnie zbadane. Również jako część postępowań sądowych przeciwko producentowi. Analizowane były zarówno zdarzenia podczas samych zabiegów, kod źródłowy i schematy komponentów, jak i sposób prowadzenia projektu. Badania prowadziła Nancy Leveson, która do dzisiaj pozostaje największym światowym ekspertem w dziedzinie badania przyczyn wypadków związanych z oprogramowaniem. Jej publikacje na temat Therac-25 można przeczytać tutaj i tutaj.
Warto tutaj zwrócić uwagę, iż jako główną przyczynę tragedii raport wcale nie wskazuje błędów w sofcie. Bugi w końcowym sofcie to jedynie skutek błędów popełnianych przy projektowaniu systemu, prowadzeniu projektu i testowaniu. Te błędy to między innymi:
- Niewystarczająca analiza ryzyka – skupienie się na ryzyku sprzętowym ignorując zagrożenia związane z softem.
- Słaba dokumentacja.
- Niewystarczające testy – brak testów akceptacyjnych na gotowym urządzeniu. Soft i HW testowane oddzielne i składane w całość dopiero w szpitalu.
- Usunięcie dodatkowych zabezpieczeń mechanicznych i elektrycznych.
- Brak review kodu, ale także wymagań, czy architektury aplikacji.
- Zła reakcja na błędy zgłaszane przez użytkowników – wykluczenie możliwości błędów w kodzie.
- Niezrozumiałe dla operatora komunikaty o błędach np. MALFUNCTION 54 bez żadnego opisu co to oznacza, ani jak postępować w takim przypadku. Dodatkowo operator mógł taki błąd skasować i kontynuować pracę z urządzeniem.
Przypadek Therac-25 był istotną lekcją dla twórców systemu i wyciągnięte wnioski posłużyły do stworzenia normy IEC 62304 regulującej wytwarzanie urządzeń medycznych.