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 nawet 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ę, że 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. Jeżeli 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ę, że 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 ręcznie 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ę, że 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ł ważną lekcją dla twórców oprogramowania i wyciągnięte wnioski posłużyły do stworzenia normy IEC 62304 regulującej wytwarzanie urządzeń medycznych.