Mark Russinovich: Der gescheiterte Versuch etwas zu zippen

Mark Russinovich ( Sysinternals ) ist mitunter auch so etwas wie ein Sherlock Holmes. In seinem Blog berichtet er von einem Problem mit der "Senden an Zip-komprimierten Ordner" Funktion. Das spannende dabei ist weniger, dass er den Fehler hat, sondern wie er mit Werkzeugen auf die tatsächliche Ursache des Problems stößt. Hier die Übersetzung seines Originalartikels .

Eines Tages hat Bryce versucht, mittels der Explorer Funktion Senden an --> ZIP-komprimierten Ordner die aktuellsten Process Monitor Source Code Updates an mich zu senden.

Anstatt dass der Dialog erscheint, mit Fortschrittsbalken und anschließender Möglichkeit einen Dateinamen Namen zu vergeben, hat der Explorer mit folgender Meldung abgebrochen:

Bryce war verwirrt. Der Fehler schien keinen Sinn zu ergeben, denn er hatte ja Lesebeechtigung auf den ausgewählten Dateien, die er zudem ja gerade editiert hatte. Und die Komprimierung sollte ja auch auch nicht in einer gescheiterten Suche enden,... dennoch auch wiederholte Versuche halfen nicht, selber Fehler, wenngleich diesmal nach einer anderen Anzahl von Dateien, die gepackt wurden.

Der Zufall wollte es, dass ich in diesem Moment gerade zu Bryce ins Zimmer kam und er konnte mir so das Verhalten gleich noch ein paar Mal zeigen. Nun waren wir beide perplex. Zeit für eine Untersuchung! Ironischerweise war das geeignete Werzeug dafür... der nicht-packbare Process Monitor.

Wir starteten den Process Monior, haben den Fehler reproduziert, stoppten den Capture und durchsuchten dann die tausenden Operationen im Trace nach Fehlern. Wir stießen dabei auf riesige Mengen von "NICHT GEFUNDEN" Fehlern am Anfang des Logs, was darauf schließen läßt, dass eine Applikation vor der eigentlichen Operation das Vorhandensein einer Datei prüft. Da waren buchstäblich hunderte solcher Einträge, alle mit Verweisen auf die zu erstellende ZIP-Datei:

Das war beunruhigend, aber nicht direkt mit unserem Problem verbunden. Ich speicherte es geistig mal ab um darauf später noch zurückzukommen.

Mehrere hundert Einträge später stießen wir auf eine Zugriffsverletzung ("SHARING VIOLATION") die nach einer eingehenderen Untersuchen verlangte:

Wenn ein Prozess eine Datei öffnet kann sie festlegen ob und wie sie die Datei mit anderen Prozessen teilen will, während der Zugriff erfolgt. Drei verschiedene Typen gibt es: Lesen, Schreiben und Löschen, und jeder Typ wird mit einem Flag repräsentiert, das an die CreateFile API weitergereicht wird. In der Operation, wo der Zugriff fehlgeschalgen ist, hat der Explorer kein Flag weitergereicht, was meint, dass er nicht wollte dass die Datei mit anderen Prozessen geteilt wird, wie man im SharedMode Feld sehen kann:

 

Damit ein Öffnen erfolgreich ist, müsse der ShareMode des öfnnenden Prozesses kompatibel sein, mit jene, ShareMode des Prozesses, der die Datei bereits offen hat. Die Erklärung für die Zugriffsverletzung ist also, dass offenbar ein anderer Prozess die entsprechenden Flags nicht gesetzt hat.

Zurück im Trace zeigt sich, dass erst eine Öffnen Operation durch den Explorer stattfindet, direkt gefolgt von einer weiteren Öffnen-Operation - die dann scheitert. Das gescheiterte Öffnen der selben Datei erfolgt durch einen Prozess namens InoRT.exe. (Das Schließen der Datei ist im Screenshot nicht sichtbar, weil es erst lange nach dem erfolglosen Versuch des Explorers kommt, die Datei zu öffnen.) Das bestätigt, dass der Explorer unwillig ist, die Datei nicht-exklusiv zu öffnen, obwohl InoRT bei seinem Öffnen der Datei sehr wohl die Öffnen, Lesen und Löschen Flags gesetzt hat.

Process Monitor erwies sich auch weiter hilfreich: InoRT.exe hält die Datei offen, wenn dann der Explorer sie versucht zu öffnen, kommt es zu der Zugriffsverletzung und damit zu der mißverständlichen Fehlermeldung. Nächster Schritt war also zu identifizieren, wer/was/wie InoRT ist, damit wir mit einer Lösung oder einem Workaround weiterkommen. Process Monitor beantwortete auch das mit dem Tooltip.

eTrust, der Antivirus Scanner von Computer Associates, öffnete offensichtlich die Datei um sie nach Viren zu durchsuchen, funkte da aber dem Explorer dazwischen. Eigentlich sollte ein Virenscanner für das System unsichtbar agieren, also handelte es sich hierbei um einen Bug von eTrust. Der Workaround für Bryce war das setzen eines Verzeichnis Filters, dass das Quellverzeichnis vom Real-Time Scanner des Antiviren Programms ausgeschlossen hat.

Ich konnte den Fehler nicht nachstellen, als ich zurück in mein Büro kam, also vermutete ich einen Versionunterschied von InoRT bei mir bzw. Bryce. Die Event Eigenschaften der Process Seite von Process Monitor zeigen für das Inort.exe Ereignis dass Bryce die Version 7.01.0192.0001 hatte, während bei mir die aktuellere 7.01.0501.0000 lief.

Warum wir verschiendene Versionen hatten, ist nicht ganz klar, da beide ausgerollten Images von der Microsoft IT gemanaged werden, aber offenbar hat Computer Associates den Bug in neueren Releases gefixt.

Nun wendete ich meine Aufmerksamkeit wieder dem ineffizienten Pack-Features des Explorers zu. Ich zeichnete mit Process Explorer einen Trace auf, wo ich genau eine einzige Datei packte und zählte die damit verbundenen Operationen. Alleine in diesem simplen Fall konnte ich feststellen, dass der Explorer das Ziel-ZIP 14 mal öffnete, davon 12 mal BEVOR die Datei überhaupt erstellt worden ist - deshalb auch die NOT FOUND Ergebnisse. Daneben zählte ich noch 19 Directory Lookups. Genauso mit dem Quellfile: 28x geöffnet, die Eigenschaften wurden 17x abgerufen. eTrust hatte also genug Möglichkeiten dem Explorer reinzufunken um die Zugriffsverletzung auszulösen.

Um auch wirklich nachzuweisen, dass der Explorere selbt an dem Fehler schuld war, und nicht irgendeine Dritthersteller-Erweiterung, schaute ich in die Stacks der einzelnen Events hinein und drückte Strg+K um den Eigenschaften Dialog aufzurufen:

Zipfldr.dll, das ist die Explorer DLL für die Kompression, war in den meisten Stack Traces, das heißt, dass sie für die Verschwendung hauptverantwortlich war. Mehr noch: die Zahl an sich wiederholenden Zugriffen explodiert geradezu, wenn man mehrere Dateien komprimiert. Hier gibt es offensichtlich einige Wege den Algorithmus zu optimieren, hoffentlich sehen wir in Windows 7 eine effizientere Kompressions-Engine.

Update: Ich habe mittlerweile erfahren, dass die Kompressions-Engine in Vista SP1 einer Aktualisierung unterzogen worden ist, demnach wird sie dann weniger Datei Operationen durchführen.

Download: Process Monitor

Übersetzung / Beitrag von Georg Binder

Quelle: Mark's Blog : The Case of the Failed File Compression