7. Ein Bug
"Wie Sie vielleicht wissen, gibt es in Ada die Möglichkeit, allen möglichen Krempel mit einem neuen Namen zu versehen, Prozeduren, Datentypen, Datenobjekte, Objekte, Ausnahmesituationen, Pakete, Task-Entries, Klassen. Man nennt das auch 'Synonym-Vereinbarung', oder aus dem Englischen 'Renaming'. Das hört sich einfach an und ist es in den meisten Fällen auch - ausgenommen in solchen Fällen, in denen man Entitäten einen Namen gibt, die vorher selbst keinen eigenen Namen hatten.
"So kann man zum Beispiel einem Array-Element einen Namen geben, oder einer Slice, also einem Teil eines Arrays, oder einer Record-Komponente, oder einem dynamisch generierten Objekt oder einem Teil eines solchen Objektes, das nur über einen 'access'-Wert erreichbar ist, also über eine Adresse. Manchmal gewinnt man dadurch etwas an Geschwindigkeit. Wenn man etwa einem Element eines zehndimensionalen dynamischen Array-Objektes einen eigenen Namen gibt, dann spart man sich zur Laufzeit die Rumrechnerei mit den verschiedenen Grenzen der verschiedenen Array-Dimensionen. Es findet praktisch nur noch ein Zugriff über eine Adresse statt, und diese Adresse muß man sich nur ein einziges Mal ausrechnen. Deshalb macht man das recht gerne.
"Andererseits, wenn man eine zehndimensionale Slice eines zehndimensionalen Arrays mit einem eigenen Namen versieht, dann sind an diesen Namen ja auch die Indexgrenzen dieser Slice gebunden, die dann in einem geeigneten Datenobjekt aufbewahrt werden müssen, um die Einhaltung der Indexgrenzen beim Zugriff auf diese Slice zu überprüfen. Nicht ganz einfach, wenn Sie bedenken, daß ein solches Objekt ja nicht einmal einen zusammenhängenden Speicherbereich belegen muß."
Miesner kommt in Fahrt. Es ist, als ob er sich aussprechen müßte. Ich komme kaum noch mit, aber Miesner gehört zu den Menschen, die einem den Eindruck vermitteln, daß man wenigstens im Moment alles versteht. Ich werde noch mit Rodrigo genauer darüber sprechen müssen.
Einen Moment lang bemerke ich, wie die Straub zum Fenster hinaussieht. Sie langweilt sich. Wahrscheinlich versteht sie gar nichts, aber sie kann nicht eingreifen, weil sie immer noch nicht weiß, wie dienstlich dieses Gespräch nun wirklich ist. Wenigstens begreift sie, daß der Miesner hier nicht in seiner Eigenschaft als Hobby-Computerist, der er vielleicht auch ist, spricht, sondern aus dringenderem Anlaß.
Von der Stadtoberfläche ist jetzt überhaupt nichts mehr zu sehen, so dicht ist der Regen. Selbst durch diese dicken Scheiben hört man das schwache Grollen seines Aufschlagens, und es zucken jetzt auch häufiger Blitze hinter den Wolken. In diesen Breiten ist dieses Wetter fast die Regel. Im zwanzigsten Jahrhundert, bevor der Treibhauseffekt spürbar wurde, war es auf dem Nordatlantik ein bißchen besser.
Miesner fuchtelt mit den Händen herum, als wolle er vor unseren Augen Speicherbereiche anschaulich in der Luft aufmalen. Es ist ihm wichtig, daß wir mitkommen.
"Diese Synonymvereinbarung ermöglicht also, auf einem alternativen Weg auf Objekte oder deren Teile zuzugreifen. Und das ist das Problem: Für solche Zugriffsbeschränkungen, wie sie durch das 'pragma SHARED' und seine Verwandten bewirkt werden, müßte auch der Zugriff über die alternativen Namen kontrolliert werden. Und da sich dieser Zugriff über eigens zu diesem Zwecke abgestellte Adressencontainer abspielt, müßten diese Adressen auch auf den neuesten Stand gebracht werden, wenn sich die Lage der Datenobjekte im Speicher ändert, weil gerade eine Garbage-Collection abläuft.
"Das ist beides implementiert: Zugriffskontrollen für Synonym-Objekte und Umsetzen der Adressen bei Garbage-Collections. Beides funktioniert - jeweils für sich alleine. Beides zusammen nicht. Oder sagen wir mal, es läßt sich nicht beweisen, daß es funktioniert. Der Aufwand bei der Implementierung des Compilers und des Runtime-Systems war einfach zu groß. Da gab es Budget-Kürzungen. Ich weiß das, weil ich bei jenem Compiler-Projekt tätig war. Ich ließ mich dann in ein anderes Projekt versetzen, nämlich in die Herstellung des Steuersystems für diese Stadt, wo ich dann mit unserem eigenen Compiler aus der Anwendersicht konfrontiert wurde."
Rodrigo kratzt sich am Kopf:
"Kann man das so ungefähr verstehen, warum Garbage-Collection, Synonymvereinbarung und pragma SHARED sich nicht vertragen?"
Miesner zuckte mit den Schultern: "Ich will mal ein Beispiel versuchen. Ich sage aber nicht, daß das Problem genauso aussehen könnte.
"Nehmen wir mal an, eine Datenstruktur wird zur Laufzeit auf Read-only gesetzt. Verschiedene Tasks dürfen sie also lesen, keiner darf schreiben. Teilen dieser Datenstruktur werde alternativ durch Synonymvereinbarung ein neuer Name zugeordnet. Auch über diesen Zugriffspfad dürfen mehrere Tasks in der Datenstruktur lesen. Dann schlägt eine Garbage-Collection zu.
"Die Garbage-Collection ist auch eine Task, die exklusiv dem Runtime-System zugeordnet ist. Sie setzt zunächst den Zugriff auf diese Datenstruktur auf 'disable'. Damit werden alle laufenden Zugriffe angehalten. Dann wird der Speicher reorganisiert und ebenso die Zugriffsadressen auf die betroffenen Datenobjekte und eventuelle Puffer. Danach wird der Zugriff wieder auf read-only gesetzt, und das Lesen durch diese zugreifenden Tasks kann weitergehen. Wichtig zu merken: Während der Garbage-Collection sitzen alle Tasks, die gerade in dem Datenobjekt gelesen haben, untätig herum.
"Wer nicht untätig herumsitzt, ist oder sind die Tasks, die auf das Datenobjekt über einen anderen Namen zugreifen. Im Gegenteil. Da andere Tasks blockiert sind, kriegen sie sogar besonders viel Rechenzeit und besonders viele Prozessoren.
"Über den Umweg des Synonyms in das Datenobjekt schreiben dürfen diese Tasks auch nicht. Die Implementierung des 'pragma SHARED' und seiner Verwandten stellt das sicher. Was nicht funktioniert ist die Unterbindung des Lesens trotz der ablaufenden Garbage-Collection. Es wird zwar die Adresse, die dem alternativen Namen zugeordent ist, während der Garbage-Collection ebenfalls umgesetzt. Doch, und das ist das wesentliche, eine kleine Weile lang ist diese Adresse nicht konsistent mit dem, was tatsächlich im Speicher steht. Ein Lesezugriff kann also etwas ganz anderes liefern.
"Das erklärt aber noch nicht ihr Problem mit den blockierten Ventilen der Auftriebszellen. Da gäbe es verschiedene Möglichkeiten, und ich muß Ihnen auch gleich sagen, daß ich nicht die Informationen habe, zwischen ihnen eine definitive Entscheidung zu treffen.
"Eine Möglichkeit ist, daß die einem alternativen Namen zugeordnete Adresse wieder auf eine gültige Datenstruktur zeigt, so, wie es der diesem Namen zugeordnete Datentyp vorschreibt. Dann sind die Informationen in dieser Datenstruktur - also mit Sicherheit Teil eines Stadtmodells - in sich konsistent, jedenfall so konsistent, daß das Programm nicht abstürzt. Nur - es ist ein falsches Modell. Dort kann zum Beispiel die Information liegen, daß die Ventile geschlossen sind. Sie waren es ja auch, heute morgen vor vier Uhr. Dann können sie natürlich nicht noch einmal geschlossen werden. Das würde die Stellmotoren beschädigen, und so etwas läßt das Programm nicht zu."
"Großer Gott." murmelt Rodrigo.
"Eine andere Möglichkeit ist, daß wir, also daß das System sich in eine klassische Deadlock-Situation hineingesteigert hat, daß also die Tasks, die die Antriebsmaschinen, die Reaktoren und die Ventile der Auftriebszellen kontrollieren, sich alle gegenseitig blockieren. Ich glaube nicht so recht daran, aber als prinzipielle Möglichkeit können wir das einmal im Raume stehen lassen."
"Aber - der Lastausgleich ..." sage ich.
"Genau." nickt Miesner, "Der Lastausgleich. Der funktioniert noch. Sowohl die Steuerung der Einlaufmenge in die einzelnen Auftriebszellen als auch die Steuerung der einzelnen Antriebsmaschinen im Hinblick darauf, daß sich keine Kraftfelder aufbauen, die die Stadt beschädigen, das alles funktioniert noch. Das sind nämlich wieder andere Tasks. Wir können sogar sicher sein, daß diese Tasks noch arbeiten. Gerade die Antriebsmaschinen, die Sie ja auf Vollast gefahren haben, sind bei weitem stark genug, die Stadt zu zerbrechen."
"Das heißt ..." sagt Rodrigo, und ich fahre fort: "Daß wir nur zufällig noch am Leben sind."
"So ist es."
Ich sehe dem Gesicht der Straub an, daß sie anfängt, zu begreifen, was sich hier abspielt. Ich versuche, ihr zuvorzukommen. Wenn sie sich als Schichtleiter und Vorgesetzte aufspielt, dann ist an eine disziplinierte Arbeit sowieso nicht mehr zu denken. Außerdem - wie ständen wir dann vor dem Miesner da?
Miesner steht mindestens eine Minute lang vor dem Fenster, mit dem Rücken zu uns, und schaut den Wolken zu, wie sie um den Turm herum jagen und jede Sekunde die Sicht verändern. Manchmal können wir den Wald da unten nicht einmal ahnen, und der Kontrollraum des Turmes schwebt wie eine seltsame Ballongondel oder ein Raumschiff durch endlose Wolkenschichten, die sich vielleicht himmelhoch über der wilden Oberfläche eines fernen, gewalttätigen Planeten türmen. Dann, plötzlich und ohne Vorwarnung, sieht man unten doch wieder schwankende Baumwipfel, und man wundert sich, daß sie nicht schon alle abgerissen worden sind. Ob Miesner an das Wetter denkt, ob er die Urgewalten genießt, oder ob er im Geiste nur seine Speicherstrukturen durchforscht und neue Wege sucht, um dem Problem zu Leibe zu rücken? Vielleicht nimmt der den Zorn des Wetters gar nicht so recht wahr.
"Und doch" sagt er schließlich, "ist das ja alles nur Theorie. Die eigentliche Ursache kann etwas ganz anderes sein. Etwas, woran wir ganz zuletzt denken. Zum Beispiel wurde während des Projektes mehrfach die Version des Ada-Compilers gewechselt. Was man aber nicht gemacht hat, um Rechenzeiten zu sparen, ist, das gesamte System noch einmal von vorne zu übersetzen. Das wäre am saubersten gewesen. Wir glauben zwar, daß die Bibliotheken von Compilerversion zu Compilerversion kompatibel sein sollten, aber ganz sicher kann man nie sein. Jede Änderung am Compiler kann Änderungen in den Datenstrukturen der Bibliotheken nach sich ziehen. Wer weiß, was wir da zusammengebunden haben."
Ich weiß jetzt nicht, von welchen Bibliotheken er redet. Das einzige, was sicher scheint, ist, daß man überhaupt nicht mit vertretbarem Aufwand herauskriegen kann, woran das System nun krankt, sondern nur, daß es krankt. Wenn er noch länger nachdenkt, wird er wahrscheinlich noch mehr mögliche Ursachen herausfinden. - Ein Arzt würde in der analogen Situation mit Spannung auf die Autopsie warten, um zu erfahren, welche Diagnose denn nun richtig war!
Einen solchen Fehler in einem Programm nennt man, wenn ich mich recht erinnere, einen 'bug'. Das heißt 'Wanze'. Das Wort suggeriert eine Kleinigkeit - einen klitzekleinen Fehler eben, irgendwo in einem großen Programm, das sonst vielleicht richtig ist. Aber der kleinste Fehler kann große Auswirkungen haben.
"Was tun wir?" frage ich. Eigentlich müßte ich die Antwort geben. Ich bin der nautische Stadttechniker, und ich bin im Dienst. Aber ich weiß nicht, was ich tun soll. Die Straub wird sich sicher eine geistige Notiz machen, daß ich einmal etwas nicht weiß.
"Stellen wir alle Handlungsoptionen zusammen." sagt Miesner entschlossen, nachdem er sich umgedreht hat und dem Wetter seinen Rücken zuwendet, "Wenn wir alles aufzählen, was man tun kann, und alles wegstreichen, was sofort zur Katastrophe führt, dann bleibt das übrig, was man tun muß. Das ist die Handlungsfreiheit des kompetenten Entscheiders. Eine andere hat er nicht. Nur Dummköpfe sehen Optionen, die nicht existieren."
Große Worte. Hoffentlich hat die Straub das mitbekommen. Hat Miesner sie absichtlich so demonstrativ bei diesen Worten NICHT angesehen? Man kann nicht sicher sein, weil es ja eigentlich sehr viele Dinge gibt, die man zu einem gegebenen Augenblick nicht ansieht.
"Ventile zu geht nicht. Antriebsmaschinen aus geht auch nicht, das haben Sie ja auch schon ausprobiert."
"Ne, habe ich nicht."
"Oh, dann habe ich mich falsch erinnert. Versuchen Sie es, bitte."
Zurück zu meiner Hauptseite
Sie sind Leserin dieser Seite Nummer