Startseite | Info | Community | Entwicklung | meinReactOS | Kontakt
|
|
Community > ReactOS Newsletter Archive > ReactOS Newsletter: Newsletter 62Newsletter 62by Z98 on 2009-07-21 PSEH Bug verfälschte StackIn NT Betriebssystemen wird die strukturierte Ausnahmebehandlung (PSEH) benutzt um den Zugriff auf die Speicherpuffer und den auslagerbaren Speicher des User Modus aus dem Kernel Modus heraus sicherzustellen. Diese Anforderung war der Grund für die Implementierung der PSEH Library durch KJK::Hyperion, weil GCC keine Ausnahmebehandlung (SEH) unterstützt. Da der letzte Versuch SEH Unterstützung in GCC zu implementieren gescheitert ist benutzt ReactOS auch weiterhin PSEH. Als das ARM Team Code vor kurzem eingefügt hat, kam ein sehr bösartiger Bug in der PSEH Library zum Vorschein. Bei der Untersuchung dieses Bugs und der dazu notwendigen Codeanalyse entdeckte KJK einen weiteren schwerwiegenden Bug, der große Probleme bei der Ausführung von Exceptions verursachte. Der erste Bug drehte sich um verschachtelte “try/catch” Blöcke. Zur Verwaltung der Schachtelung von Exceptions wird die Schachtelungstiefe „Trylevel“ und andere Daten auf einem Stack abgelegt. Wird ein Level der Schachtelung aufgelöst, muss der betreffende Datensatz vom Stack entfernt werden. Nun wurde in geschachtelten Exceptions bei der Auslösung und dem Einfangen einer Exception im inneren Block eine weitere Exception im äußeren Block ausgelöst. Der Code sprang aber nicht wie erwartet zu dem “catch” statement im äußeren Block, sondern zu einem im inneren Block. Dadurch sprang die Programmausführung ständig in den inneren Block zurück und nicht aus der Exception heraus. Diese Endlosschleife wurde ausgelöst, da der „Trylevel“, beim Verlassen des inneren Blocks nicht wie erwartet vom Stack entfernt wurde und PSEH sich immer noch im inneren Block wähnte. Die machte das Betriebssystem jedoch unbenutzbar sobald der Bug ausgelöst wurde. Dies geschah zum Beispiel wenn das automatisierte Testsystem einen Test mit eingebundenem ARM Code durchführte. Mit der Hilfe von Stefan Ginsberg hat KJK es geschafft den Grund des Bugs in den geschachtelten “try/catch” Blöcken zu isolieren und zu beseitigen. Nun arbeiten die automatischen Tests wieder. Der zweite Bug war dem Ersten recht ähnlich, da auch hier der Ausführungsrahmen nicht vom Stack entfernt wurde und dies beim Exceptionhandling zu einem komplett zufälligen Resultat führte. Das Schlimme an diesem Bug war, dass er auch ohne die geschachtelten „try/catch“ Blöcke ausgelöst wurde. Er führte zwar nicht zum Absturz des Betriebssystems, aber zu einer zufälligen Stackverfälschung, was auch andere Dinge beeinträchtigte und schlussendlich schwer zu verfolgende Speicherverfälschungen hervorrief. Da das jedesmal passierte wenn eine Exception in SEH ausgelöst wurde, wäre es nicht überraschend wenn dies der Grund für viele zufällige Abstürze war an denen ReactOS seit der Einführung von PSEH2 gelitten hat. Ironischerweise existierte ein identisches Problem auch in PSEH1, welches auch den gleichen Fix hatte. Weiterhin hat KJK's PSEH Testsuite mitgeholfen den Bug zu finden, da die überwiegende Mehrheit der Tests scheiterte, als KJK's eine bis dahin fehlende Plausibilitätsprüfung eingebaut hatte. Nachdem der Bug gefixt war, bestanden wieder alle Tests die PSEH Testsuite. topXLATEOBJXLATEOBJ ist eine Datenstruktur mit einigen assoziierten Funktionen, die helfen Farben zwischen verschiedenen Oberflächen zu übersetzen, wie z.B. von einer Bitmap zum Farbformat eines Bildschirms. Da diese Operation andauernd durchgeführt wird, muss diese auch sehr schnell sein. Das war die ReactOS Implementation unglücklicherweise aber nicht, da diese Funktionen eine Reihe von “if/else” Ausdrücken zur Entscheidung beinhalteten wie die Farbumsetzungen durchzuführen seien. Timo Kreuzer ersetzte dies Funktionsweise mit schnellen, sog. “Callback” Funktionen, die über einige optimierte Funktionen verfügten und nur das ausführten, was auch wirklich notwendig ist. Eine weitere Änderung die Timo umsetzte ist die dynamische Allozierung von XLATEOBJ Strukturen auf dem Stack. Bei der Ausführung einer bitblt Operation wird nicht wie bisher diese Struktur im auslagerbarem Speicherpool alloziert und sondern nur auf dem Stack. Normalerweise wird eine Pixel für Pixel Übersetzung durchgeführt, wenn verschiedene Farbformate umgesetzt werden. Bei der Benutzung des Musterpinsels wird die DrvRealizeBrush Funktion benutzt, die wie der Name bereits besagt, ein Quellmuster auf die Zieloberfläche projeziert, was Realisierung genannt wird. Vor der Benutzung des Musterpinsels wird der Treiber durch das GDI aufgerufen. Dabei muss um das Pinselmuster auf das Zielfarbformat übersetzt werden. Zur selben Zeit erzeugt das GDI seine eigene Pinselrealisation, falls der Treiber berichtet, dass die Karte diese Funktion nicht unterstützt. Bisher wurde dies von ReactOS nicht so umgesetzt, aber Timo hat die Modifikationen in seiner Arbeitskopie durchgeführt und arbeitet nun daran, sicher zu stellen, dass dadurch keine Regressionen entstehen. Wenn hinreichend getestet wurde und klar ist dass diese Implementation keine negativen Seiteneffekte erzeugt, werden seine Änderungen auch in den Trunk eingestellt. topArwinssAleksey Bragin erzeugte kürzlich einen neuen Ableger, Arwinss genannt, welches scheinbar eine andere Neuerschaffung des Win32-Subsystems darstellt. Er schickte auch eine Email umher, warum er es tat und warum in dieser besonderen Verfahrensweise. Der Grund waren Alekseys Frust mit dem bestehenden Win32-Subsystem und dessen viele Fehler. Während einige andere Entwickler lang und hart daran arbeiteten, das System lauffähig zu bekommen, sind dort trotzdem grobe und hartnäckig Fehler. Viele von diesen entstanden durch Hacks und falschen Implementierungen in der Vergangenheit und die Behebung käme einer Neuerschaffung gleich. Aleksey entschied deshalb, zur Beschleunigung alles einfach neu zu schreiben. Es gibt einen umfangreichen Teil von Wine-Quellcode im Branch, importiert vom letzten Wine Release. Diesmal wurde die Architektur von Wine unverändert gelassen. Die Hierachie der Aufrufe in Windows kann sehr komplex sein, vieles davon ist nicht in Wine verdoppelt. Aleksey setze diese Vereinfachung fort und fasste die Layer zusammen. Er erzeugte eine wesentlich kleinere Win32-Komponente für die Kernelseite im Subsystem, auch wieder mit Code von Wine, damit es zu den Wine Usermode DLLs passt. Er fügte aber seine eigenen Veränderungen hinzu, damit alles auf einem NT OS läuft. Diese Änderungen sind wahrscheinlich am meisten kontrovers. Momentan fühlt sich das nach dem Worten von Kamil Hornicek an wie ROS 0.1.0. Textfelder sind total verschoben und Farbfehler tauchen auf. Das ist erwartet worden, aber Funktionalität wird mehr oder weniger gelähmt sein so lange. Einige Entwickler haben die Arbeit Alekseys kommentiert, und nicht alle unterstützen seine Bemühungen. Timo Kreuzer wies darauf hin, dass es langfristig gesehen dem Ziel das Win32 Subsystem korrekt zu implementieren schaden könnte. Timo ist einer der Entwickler, die eine Implementierung für wichtig halten die nicht nur die Win32 Schnittstelle implementiert, sondern eine Kopie des gesamten Subsystems mit sämtlichen dazugehörigen Layern ist. Das mag zwar zu Anfang wie eine Menge unnötiger Arbeit aussehen, aber Timo ist überzeugt davon, dass es zu einer sehr viel höheren Kompatibilität führt, als Wine wegen der benutzten Abkürzungen je erreichen könnte. Alekseys kleines Projekt könnte einigen Ärger verursachen, zumindest bis die Bedenken die andere Entwickler entwickeln könnten ausgeräumt sind. Andererseits schafft es auch die Möglichkeit eines "sauberen" Anfangs, mit dem die Implementierung von Anfang an zu 100% korrekt ohne Umwege durchgeführt werden kann. Nur die Zukunft wird zeigen, ob das wie geplant funktioniert oder nicht.
top |