Fehlerfreiheit von Software

Matthias Jauernig
11.09.05
www.linux-related.de

1.      Einführung

Manchmal scheint es wie verhext: der Computer streikt und stürzt ab, Handys verweigern den Dienst und Digitalkameras lassen sich nicht mehr zur Mitarbeit bewegen. „Technikpannen“ wie diese haben wir alle schon einmal bewusst oder unbewusst miterlebt, die Industrie kosten sie jährlich mehrere Milliarden Euro. Auch wenn es viele Gründe dafür geben kann, nicht selten sind Softwarefehler die Wurzel dieses Übels. Im besten Fall belustigend bis ärgerlich, können sie im schlimmsten Fall Millionen von Euro verschlingen oder noch schlimmer vielen Menschen das Leben kosten. Und die Brisanz des Themas verschärft sich: kaum mehr gibt es Bereiche, in denen Software nicht mehr zum Einsatz kommt – Software ist (für viele unsichtbar) immer und überall. In einem durchschnittlichen deutschen Haushalt gibt es schon heute 200-300 Kleinstrechner („Mikroprozessoren“), die alle von Software gesteuert werden, z.B. in Uhren, Waschmaschinen, Mikrowellen, Lichtanlagen und elektrischen Zahnbürsten. Dies zeigt die Wichtigkeit der Thematik: für die Informatik, die Softwareentwicklung, die Gesellschaft und jeden einzelnen von uns, der sich täglich mit den Auswirkungen von Softwarefehlern herum plagen muss.

Fehlerfreiheit als Teil der Funktionalität von Softwareprodukten zu garantieren bedarf einer Reihe von Methoden, die ich im Folgenden kurz vorstellen will.

Allgemein unterscheidet man zwischen „validierenden“ und „verifizierenden“ Verfahren. Der Unterschied besteht darin, dass bei den validierenden Verfahren das Softwareprodukt auf Fehler getestet wird, wohingegen man mit der Verifikation die Richtigkeit der Software zu beweisen versucht.

2.     Validieren von Software

Beim Validieren von Software bzw. einzelner Komponenten einer Software wird diese getestet mit dem Ziel Fehler zu erkennen. Vergleichen kann man dies mit dem Konstruktionsprozess im Automobil-Bau: die Validation von Software entspräche hier etwa dem Testen eines Autos (oder seines Prototyps) unter realen Bedingungen auf einer Teststrecke.

Testende Verfahren lassen sich weiter unterteilen. Die wichtigsten Hauptgruppen sind dynamische und statische Tests.

Bei den dynamischen Testmethoden existiert eine Vielzahl von Verfahren. Bei allen wird das zu testende Programm mit konkreten Eingabedaten ausgeführt. Im Vergleich mit der Auto-Konstruktion könnte dies z.B. eine Testfahrt unter bestimmten Umweltbedingungen mit einer bestimmten Menge an Treibstoff bedeuten.

Wichtig in dieser Kategorie sind die funktionalen Tests. Z.B. lässt man die Software unter „Normalbedingungen“ testen, indem man einen Satz von typischen Eingabedaten nimmt oder eine Reihe von Versuchspersonen, die das Programm eine Weile bedienen sollen um bestimmte Funktionen zu testen. Andererseits muss man auch unerwartete, extreme Eingaben berücksichtigen und auf Fehler hinsichtlich solcher Datensätze prüfen. Sollten bei diesen Tests Fehler entdeckt werden, so kann man sie in einer Fehlerliste mit detaillierter Beschreibung zusammenfassen und nachträglich im Bugfixing-Prozess beheben.

Manche Softwareanbieter führen teilweise öffentliche Test-Phasen durch und geben Betaversionen ihrer Software heraus, um die unvorhersehbar vielfältige Nutzung durch verschiedene Anwender testen und kommentieren zu lassen. Solche Software nennt man scherzhaft auch „Bananen-Software“, weil sie erst beim Kunden reift.

Den dynamischen Testverfahren gegenüber stehen statische Tests. Im Automobilbau würde man sich hierbei die „Innereien“ eines Autos anschauen, um Schwachstellen bzw. Fehler zu finden.

In der Softwaretechnik schaut man sich äquivalent dazu den Quelltext einer Software an, den der Programmierer erstellt hat und aus dem das zukünftige Programm entsteht. Fallen hierbei Fehler auf, so kann man sie direkt beheben oder in einem Bericht dem Programmierer mitteilen.

Allen Testverfahren ist gemein, dass es eine Vielzahl von Tools gibt, mit welchen sie sich teilweise automatisieren lassen. Software zu testen ist effektiv, wird dadurch doch eine Vielzahl von Fehlern gefunden. Validation sollte damit unverzichtbarer Bestandteil der Entwicklung einer jeden Software sein.

Es muss allerdings zu denken gegeben werden, dass die getestete Software am Ende nur so gut und fehlerfrei sein kann wie die Tests selbst. Auch sollte man bedenken, dass Testverfahren nur die Anwesenheit von Fehlern beweisen können, aber nicht deren Abwesenheit. Es ist also weiterhin möglich und bei großen Projekten unausweichlich, dass die entwickelte und getestete Software weiterhin Fehler enthält, vorausgesetzt man hat nicht jede mögliche Eingabe berücksichtigt. Vergleichend seien hier Tests im Automobilbau genannt: aus dem Bestehen eines Tests, z.B. des „Elch-Tests“, lässt sich nicht darauf schließen, dass das Auto in anderen Bereichen, z.B. beim Benzinverbrauch, nicht kläglich versagt.

3.     Verifizieren von Software

Im Automobilbau wie in der Softwareentwicklung müssen Produkte bestimmte Spezifikationen erfüllen, um abgenommen zu werden. Ein Auto darf nur eine bestimmte Menge Sprit verbrauchen, muss schadstoffarm sein und internationale Sicherheitsbestimmungen erfüllen. Software setzt sich meist aus einzelnen Komponenten zusammen, die über Funktionen aufgerufen werden. Für die einzelnen Funktionen lassen sich ebenfalls Spezifikationen festlegen, welche erfüllt werden müssen, sodass die Funktion als korrekt gilt. Im Gegensatz zu den testenden Verfahren (der Validation) wollen verifizierende Verfahren die Korrektheit solcher Spezifikationen beweisen.

Eine Spezifikation sieht dabei so aus: man legt zunächst eine Reihe von Vorbedingungen fest, welche beim Eintritt in eine Funktion gegeben sind. Dann bestimmt man die Nachbedingungen, welche nach Abarbeit der Funktion gelten sollen. Um zu beweisen, dass eine Funktion ihre Spezifikation einhält, gilt es nun zu zeigen, dass sich aus den gegebenen Vorbedingungen nach Abarbeit der Funktion die spezifizierten Nachbedingungen ergeben.

Beim Beweisen der Korrektheit von Funktionen greift man im Wesentlichen auf mathematische Beweismethoden und logische Schlussfolgerungen zurück. Für jede Anweisung einer Funktion überprüft man beispielsweise, wie sich die zuvor definierten Vorbedingungen ändern. Ergeben sich am Ende in jedem Fall die Nachbedingungen, d.h. unter Einschluss aller möglichen Fälle von Eingaben, so ist die Funktion bewiesenermaßen korrekt.

Oft erfolgt die Verifikation von Software werkzeug-unterstützt. Allerdings ist voll-automatisches Beweisen von Programm-Eigenschaften praktisch unmöglich. D.h. der Programmierer muss mithelfen, indem er das Programm und gleichzeitig den Beweis dafür schreibt. Werkzeuge sind dann in der Lage zu verifizieren, dass beides zueinander passt.

Nun könnte man die Verifikation als Wundermittel zur Lösung des Problems der Softwarefehler ansehen, weil damit schließlich die Korrektheit bewiesen wird. In der Praxis ergeben sich allerdings arge Probleme. Zum einen wäre da die Korrektheit: wenn die Spezifikation für eine Funktion falsch erstellt wurde, nützt auch der Beweis nichts. Ebenso stellt sich doch die Frage, wer denn die Werkzeuge zur Verifikation von Programmen selbst verifiziert.

Noch schwerwiegender als diese Probleme ist die Aufwand/Nutzen-Frage (quasi das Preis/Leistungs-Verhältnis in der Softwaretechnik). Die Verifikation schon kleiner Programme ist sehr umständlich und zeitaufwendig. In Zeiten immer enger bemessener IT-Budgets und Projektpläne können sich die meisten Firmen keine Verifikation leisten. Und die Frage ist, inwieweit sich der Beweis von Programmen bei einfacheren Anwendungen wie Endbenutzer-Software lohnt.

Fazit: Verifikation ist umständlich, dafür wird allerdings die Abwesenheit von Fehlern bewiesen. Bei größeren Projekten, welche keine Fehlerfreiheit garantieren müssen, kommt sie daher nicht zum Einsatz, im Extremfall bei wenigen ausgesuchten Algorithmen. Anwendung findet sie hingegen in sicherheitskritischen Bereichen, so z.B. in der Schaltkreis-Herstellung, in der Kryptographie, in der Luft- und Raumfahrt, bei medizinischen Anwendungen und im militärischen Bereich, wo kleine unerwartete Fehler Millionenbeträge oder schlimmer noch Menschenleben kosten können.

4.     Berüchtigte Softwarefehler

„Mariner 1“, Cape Canaveral/Florida, Juli 1962:

Trägerrakete wich von vorberechneter Flugbahn ab, zerstörte sich nach 290 Sekunden selbst.

Ursache: Im Programmtext wurde anstatt eines Kommas ein Punkt gesetzt, dadurch eine nicht erwünschte Wertzuweisung ausgeführt.

Kosten: $ 80 Millionen

Eole 1“, August 1971:

1. französischer Anwendungssatellit (NASA-Start)

Meteorologisches Experiment mit 141 Wetterballons rund um die Erde mit Datenübertragung zum Satelliten. Die Ballons konnten zwei Kommandos empfangen: "Sende Daten" und "Zerstöre Dich selbst" (Notfall).

September 1971: Satellit wünschte Datenempfang, Ballons erhielten aber das Kommando zur Selbstzerstörung: 72 Ballons, die in Sichtweite lagen, explodierten.

Atomreaktoren USA, März 1979:

Programm zur Berechnung der Erdbebenfestigkeit von 5 Atomreaktoren zeigte kritische Werte. Folge: Längere Abschaltung zum Umbau der Reaktoren.

Ursache: Fehler im System (Bilden der arithmetischen Summe statt der Wurzel aus der Quadratsumme).

 

Falkland-Krieg, H.M.S. Sheffield, 1982:

Das Radarsystem der britischen Fregatte identifizierte die anfliegende argentinische Exocet-Rakete als "Freund" à Kein Alarm à Untergang des Schiffes.

A 320 Airbus, Air France, Juni 1988:

Absturz eines Airbus bei einer Flugshow nahe Mühlhausen.

Ursache: Ungewöhnliche Flugaktionen (niedrige Höhe, steiler Flugwinkel) wurden nicht von der Software unterstützt.

Geldautomat (ATM), ca. 1990:

Frau aus Vancouver wollte in Honolulu $ 1100 von ihrem Heimatkonto über einen Geldautomaten abheben, der von einem Computer in New Jersey gesteuert wurde.

Durch die große Zeitverzögerung der Satellitenverbindung und einen Protokollfehler wurde ihr das Geld nicht ausbezahlt, der Betrag aber trotzdem abgebucht.

Golfkrieg, Februar 1991:

In Dhahran, Saudi-Arabien, konnte eine irakische Scud- Rakete nicht vom hochgelobten Patriot-Abwehrsystem abgefangen werden - sie schlug in ein US-Militärlager ein und tötete 29 und verwundete 97 US-Soldaten.

Ursache: Die "Realzeit seit letztem Hochfahren" der Software der Patriot-Rakete wurde in einer einfachgenauen Gleitkommazahl abgespeichert. Lief das System länger als 8 Stunden (etwa 30 Millionen ms), traten daher Genauigkeitsprobleme auf:

Nach 100 Stunden Laufzeit ergab der immer größer werdende Zeitfehler eine Abweichung in der Berechnung der Scud-Flugbahn um 678 m! Das Design der Software sah nur 14 Stunden Einsatz vor.

Steuerprogramme, San Francisco, April 1993:

Das Programm eines Steuerberaters errechnete eine zu zahlende Steuer auf Kapitalerträge. Wegen zweier Software-Fehler wurden aber $ 36800 zuviel berechnet.

Unter Steuerberatern war diese Software weit verbreitet; wegen der komplizierten Steuerregeln verlassen sich die Experten inzwischen fast nur noch auf Programme!

Telefonprobleme, Singapur, Oktober 1994:

65 % der Telefonleitungen waren 5 Stunden unterbrochen, die restlichen Leitungen waren erheblich überlastet. Ursache: Ein Softwarefehler in einem Vermittlungsknoten pflanzte sich auf 26 der 28 Systeme aus.

„Ariane 5“, Kourou / Frz. Guyana, Juni 1996:

Nach dem Start sendete der Hauptrechner unsinnige Daten an die Triebwerke, die Rakete drohte auseinander zu brechen und sprengte sich selbst.

Ursache: die Steuerungssoftware wurde von der Ariane-4 übernommen und nicht für Ariane-5 konzipiert. Die auftretenden Geschwindigkeiten waren aber so hoch, dass die Software diese nicht richtig verarbeiten konnte; es wurden falsche Daten gesendet.

Kosten: über $ 600 Millionen

„Mars Climate Orbiter“, September 1999:

Nach 9-monatigem Flug erreichte die US-Raumsonde den Mars. Die angesteuerte Umlaufbahn lag aber 170 km tiefer als geplant; Folge: Absturz des Satelliten.

Ursache: Die Navigations-Instrumente des Herstellers lieferten Daten im englischen Maßsystem, die Software der NASA ging aber von metrischen Einheiten aus.

Kosten: $ 125 Millionen

„Mars Polar Lander“, Dezember 1999:

Das Mars-Landefahrzeug stürzte 40 m oberhalb der Oberfläche mit 80 km/h auf den Mars.

Ursache: Durch die Erschütterung beim Ausfahren der Landebeine hatten die Sensoren reagiert, was von der Software als Bodenberührung interpretiert wurde und zu einem Abschalten der Bremsraketen führte.

Ursache: Die Software wurde falsch entworfen und schlecht getestet: Bei dem einzigen Test waren 3 der 4 Sensoren falsch verdrahtet.

Kosten: $ 165 Millionen

Krebs-Bestrahlung, Panama, Februar 2001:

Zwischen August 2000 und Februar 2001 erhielten 28 Krebspatienten in gesundem Gewebe eine hohe Bestrahlung. Mindestens 5 Patienten starben daran, 15 weitere trugen schwerste Schäden davon. Im Dezember war aufgefallen, dass sehr viele der am Becken bestrahlten Patienten chronischen Durchfall bekamen.

Ursache: die Internationale Atomenergiekommission stellte fest, dass die Bediener der Therapie-Maschine falsche Daten in das Behandlungsprogramm eingegeben hatten, die von der Software nicht als falsch erkannt wurden. Davon aber waren die Radiologen ausgegangen.

 „Superbomben“, Irak-Bombardierung, Februar 2002:

Durch Software-Fehler in den neuen „Superbomben“ AGM-154A schlugen alle etwa 15 bis 250 m links vom Ziel ein.

Parteitag der Grünen, Ehingen, 2002:

Der Delegiertenschlüssel zum Landesparteitag der Grünen in Baden-Württemberg wurde unter MS Excel falsch berechnet.

Folge: es wurden 202 statt 200 Delegierte eingeladen, die Wahl der Kandidaten für die Landesliste zur Bundestagswahl konnte nicht durchgeführt werden. Folge: Imageverlust bei Bürgern, Spott von anderen Parteien, über 20.000 Euro Verlust.

Patriot-System“, Kuwait/Irak, 2003:

Batterien von Patriot-Raketen identifizierten verbündete Flugzeuge als Feinde.

Dabei wurden eine britische Maschine und eine F-16 „aus Versehen abgeschossen“, die Besatzungen kamen ums Leben.

Ursache: Softwarefehler in der Freund-/Feind-Erkennung.

Stromausfall in USA/Kanada, August 2003:               

14.08.03: am späten Abend deutscher Zeit fiel in 8 Staaten im Nordosten der USA sowie in Teilen Kanadas der Strom aus, insgesamt waren 50 Millionen Menschen abgeschnitten. Verantwortlich für die Panne war ein Softwarefehler, der im Managementsystem zur Überwachung und Steuerung von Stromnetzen beim Erzeuger FirstEnergy auftrat.

Rückruf bei Mercedes-Modellen, Juni 2004:

Wegen eines Softwarefehlers rief DaimlerChrysler rund 10.000 Transporter der Mercedes-Benz-Modelle Vito und Viano mit Dieselmotoren zurück. Ursache des Rückrufs war ein Bug in der Software, mit der die Dieselsteuergeräte ausgerüstet sind. Sie aktivierten in Situationen, in denen dies eigentlich nicht vorkommen sollte, die Kraftstoffabschaltung, wodurch der Motor ausging.

Bundesagentur für Arbeit, 2005:

Durch Softwarefehler erhielten Anfang des Jahres über 100.000 ALG2-Empfänger kein Geld. Im Juli wurde bekannt, dass ein Software-Fehler zu Hunderttausenden Meldungen von ALG2-Empfängern an Krankenkassen grundlos storniert hat. Im August wurde bekannt, dass in mehreren Tausend Fällen zuviel Geld an ALG2-Empfänger überwiesen wurde, ebenfalls aufgrund von Fehlern in der Software A2LL der BA.

5.     Fazit

Ein solch komplexes Thema wie die Vermeidung von Softwarefehlern lässt sich sicher nicht in 10 Minuten abhandeln. Der Vortrag sollte Einführung in die Thematik sein und Probleme aufzeigen, die uns alle betreffen.

Zusammenfassend lässt sich sagen, dass Verifikation wegen ihrer Umständlichkeit kein Wundermittel darstellt und nur in Einzelfällen bei kleineren sicherheitskritischen Programmen und Algorithmen angewandt wird. Demgegenüber steht mit der Validation, also dem Testen von Programmen, ein schnelles und vergleichsweise einfaches Hilfsmittel zur Verfügung. Zwar kann es nicht die Abwesenheit von Fehlern beweisen, jedoch einen Großteil jeglicher Fehler eines Softwareprodukts aufdecken. Software zu validieren sollte daher Bestandteil eines jeden Entwicklungsprozesses sein, um die Qualität des Endprodukts sicher zu stellen. Auch wenn dies unumgänglich erscheint, macht sich bei Softwarefirmen teilweise eine andere Philosophie breit. Unter Zeitdruck und Kürzung von Etat leidet auch das Testen von Software, ein schwerer und irreparabler Fehler. Denn eins ist klar: Fehler, die nach der Auslieferung eines Softwareprodukts entdeckt werden, fallen hundertfach auf die Entwickler-Firma zurück, in Form von Geld- und Zeitaufwand wie auch in Form von verlorenem Prestige.

Software steckt heutzutage in jedem elektronischen Gerät, in jedem Mikroprozessor. Sie erleichtert uns unser Leben und wird sich diesbezüglich auch zukünftig weiter verbreiten. Doch damit steigt auch das Potential für mögliche Fehler. Informatikern und IT-Managern muss es gelingen, neue Werkzeuge für das Fehler-Management zu entwickeln, Zeit und Geld für die Fehlerbeseitigung einzuräumen und vor allem gesellschaftliche Verantwortung für ihr Schaffen zu übernehmen. So und nur so ist mit dem Problem der Softwarefehler in Zukunft umzugehen, damit nicht wie in der Vergangenheit kleine Fehler zu großen Tragödien führen können, welche Millionen von Euro oder noch schlimmer das Leben vieler Menschen fordern.

6.     Quellennachweis

  • Programmfehler“, http://de.wikipedia.org/wiki/Softwarefehler
  • Software Reliability“, http://www-aix.gsi.de/~giese/swr/
  • Lehrbuch der Software-Technik“, Band 2; Helmut Balzert, 1998


(c) 2005 by Matthias Jauernig, www.linux-related.de
Dieses Dokument unterliegt der GNU Free Documentation License