Vom Bug zum Fix

Angesichts der aktuellen Vorbereitung auf das Release der KDE Software Compilation in Version 4.4 hab ich gedacht ich beschreibe mal die Schritte, die ich gehen muss um einen gemeldeten Bug in KWin zu beheben. Denke das könnte ganz interessant sein, vor allem wenn man nicht so vertraut mit der Entwicklung ist ;-)

Am Anfang steht der Bugreport. Im IRC channel #kwin gibt es einen kleinen bot, der neue Bug reports meldet. Da ich auch ein highlight auf das Wort "kwin" habe und dieses zufälligerweise in jeder Bug Meldung enthalten ist, erhalte ich eine schöne Benachrichtigung. Im Channel ist dann auch gleich die URL zum draufklicken enthalten. Wenn ich nicht am Rechner sitze, dann bekomme ich neue Bugs trotzdem mit: alle Bugzilla Mails werden auch an die kwin Mailingliste gesendet und zusätzlich hab ich in Akregator einen RSS feeds für neue Bugs (eigentlich überflüssig).

Ein Bug fällt in eine von drei Kategorien:

  • Wishlist
  • Bug
  • Crash

Wishlist ist ein Wunsch und so etwas wird idR erst einmal ignoriert. Gerade in der Zeit, in der man sich auf das Beheben von Bugs konzentriert, dürfen neue Wünsche eh nicht implementiert werden. Viele der Wünsche sind auch einfach nun ja Traumkonzert und lassen sich zwischen schwer bis gar nicht umsetzen.

Ein Bug ist ein Fehlvehalten der Anwendung. Im Falle von KWin beziehen sich die Meisten auf irgendwelche Probleme mit den Desktop Effekten. Viele der Meldungen sind sehr ungenau und nur unter bestimmten Fällen zu reproduzieren. Für einen Bug gilt eigentlich, dass er nicht besonders priorisiert ist. Außer es ist wirklich ein gravierender Bug.

Crash ist nun eine Sonderform eines Bugs: die Anwendung hat einen Nullpointer dereferenziert und ist abgestürzt. Bei KWin nicht so schlimm, da es sich automatisch neustartet, aber trotzdem unangenehm. Zum Glück sind mittlerweile die Anzahl der Crashes zurückgegangen, so dass im Normalfall keiner auftritt.

Bei allen drei Arten gilt, dass wir zuerst überprüfen müssen, ob der Bug schon existiert. In etwa 40 % der Fälle ist das so. Bei Crashreports ist das am Einfachsten: DrKonqui findet die automatisch und hängt die Nummer des Duplikats gleich dran. Leider reporten die User häufig trotzdem. In so einem Fall ist der Bug schnell weg: Nummer rein, und abschicken. Ansonsten wird die Suchmaschine im Hirn eingeschaltet und überlegt, ob man so einen Crash nicht schon mal gelesen hatte und wenn ja dann wird geschickt über die Suche von Bugzilla den passenden gefunden.

Natürlich ist es hilfreich den Bug reproduzieren zu können. Leider ist das nicht immer möglich, weil ganz bestimmte Bedingungen vorliegen müssen. Hatte aktuell so einen Fall, dass es nur crashed, wenn man Present Windows als Alt+Tab Effekt verwendet, während er aktiviert ist die Anzahl der Fenster auf 0 geht und man dann im richtigen Augenblick mit der Maus klickt. In dem Fall war dann zum Glück der Quellcode eindeutig und konnte sehr leicht auch ohne Reproduzierung behoben werden ;-)

Die Crash Reports enthalten einen automatisch generierten Stacktrace, der Aufschluss darüber gibt an welcher Stelle im Code der Crash auftrat. Dabei werden die Code Zeilen sogar genannt und manchmal sogar die Werte übergebener Variablen. Für die Datenschutzfanatiker: nein daraus lassen sich keine privaten Daten rückverfolgen. Im Falle von KWin ist das maximal, dass man erfährt auf welchen Desktop der User gerade wechselte. Komplizierte Daten werden als Zeiger auf eine Datenstruktur übergeben – aus der Adresse kann man nichts rauslesen außer, dass sie vllt. 0 war. Ist der Bug gegen KDE SC 4.3 reportet worden so stimmen sehr häufig die Zeilennummern nicht mehr. Hier ist es dann hilfreich, wenn man den Crash selbst reproduzieren kann, weil man dann die passenden Zeilennummern erhält.

Mit der Zeilennummer bewaffnet, geht es dann in die Entwicklungsumgebung und man schaut sich den Quellcode an. In den meisten Fällen macht es schlicht und ergreifend "Aha" und der Crash ist offensichtlich. Nun die berechtigte Frage: Warum trat er dann auf? Nehmen wir das Beispiel von oben mit Present Windows: es wurde nicht daran gedacht, dass es vorkommen kann, dass man mit der Maus klickt, wenn kein Fenster da ist. Der Code ist ja gedacht ein Fenster auszuwählen. Ja eine falsche Annahme. Über den Stacktrace und den übergebenen Werten ist dann erkennbar welcher Zeiger auf 0 zeigt und man kann den Code anpassen, so dass dieser Fall entweder nicht mehr auftritt oder abgefangen wird.

Der nächste Schritt ist das neubauen von KWin (zum Glück direkt aus der IDE) und testen ob der Crash behoben ist. Wenn dem so ist, dann kann der veränderte Code in das Quellcodeverwaltungssystem eingespielt werden. KDE verwendet eigentlich SVN, was aber für mich eher unpraktisch ist, deswegen nutze ich selbst git und habe einen über git-svn verwalteten Checkout von kwin. Zuerst überprüfe ich die veränderten Code Zeilen mittels git diff – das zeigt mir in der Konsole an, was sich genau verändert hat. Eine wichtige Überprüfung um nicht irgendwelchen Müll durch das Testen (debug Ausgaben u.ä.) ausversehen einzuspielen. Auch eine gute Überprüfung ob der Coding Style eingehalten wurde. Der nächste Schritt ist die Änderung mittels git add und/oder git commit (-a) als lokalen Commit einzuspielen. Hierbei gibt man eine aussagekräftige Commit Message ein und trägt mittels BUG: NUMMER den Bug ein, welcher dadurch behoben wird. Nun muss der Code mittels git svn dcommit in das KDE SVN übertragen werden. Dabei wird dank dem BUG Schlüsselwort der zugehörige Bugreport automatisch geschlossen und ein Kommentar eingefügt.

Die Änderung wurde nun aber nur in trunk eingespielt – dem Hauptentwicklungszweig und das was in mehr als einem halben Jahr mal KDE SC 4.5 werden soll. Natürlich möchte ich den Bug auch in 4.4 behoben haben und dazu muss der Patch in den branch zurückportiert werden. Würde ich nicht git verwenden, wäre das richtig einfach, denn es gibt ein Skript dafür. Würde KDE git verwenden wäre es noch einfacher. Für mich bedeutet es manuelle Arbeit. Also mittels git show den letzten Commit in eine temporäre Datei speichern und in mein Verzeichnis wechseln, in dem der 4.4 Code rumliegt. Hier kann ich mit patch -i die Änderungen lokal einspielen. Bei 4.4 geht das noch ohne irgendwelches meckern, da es im Prinzip noch der identische Code ist. Nun müsste ich eigentlich die Änderung einspielen, hab aber mein Konsolen SVN Wissen dank git verlernt und nutze nun Dolphins SVN Integration. Dolphin öffnen, an die passende Stelle navigieren, über das Kontextmenü noch mal den Diff anzeigen lassen (lieber einmal zu viel kontrolliert, als einmal zu wenig) und die Datei committen. Als Commit Message wird die gleiche Meldung wie zuvor in git verwendet, jedoch mit dem Zusatz "Backport rev SVN-Nummer" und CCBUG anstatt BUG. Dadurch wird einfach nur eine Meldung an den Bug angehängt. Und da wir ja fleißig sind, machen wir das ganze für 4.3 auch noch mal sofern der Code passt.

So wie lange dauert so etwas? Beispiel von gestern abend: Um 20:54 Uhr hat mir ein User im IRC einen Crash gemeldet, er klang komisch und ich hab sofort ausprobiert und ihn reproduzieren können. Kdevelop war bereits mit der passenden Datei geöffnet (ist eigentlich immer offen) und ich konnte direkt an die Quellcodezeile springen. Um 21:06 konnte ich dem User melden, dass der Crash in trunk und branch behoben ist. Für den Backport in einen Branch brauche ich etwa 2 min – insgesamt alse 4 (IRC Log von CIA Bot). Zum Reproduzieren, Crashen und Testen, dass es wirklich behoben ist also gerade mal vier bis fünf Minuten. Ja der war wirklich einfach ;-) Heute saß ich an einem, bei dem ich nach etwa einer Stunde erst mal aufgehört habe, weil ich ihn nicht beheben konnte. Wird aber definitiv in 4.4 (notfalls über Würgaround) behoben sein.

=-=-=-=-=
Powered by Blogilo

13 thoughts on “Vom Bug zum Fix”

  1. Ich schließe mich mal den Vorkommentierern an und freue mich schon auf die stabile Version KDE SC 4.4.

  2. Hi!
    Der Artikel ist sehr schön geschrieben, gefällt mir! Es ist immer interessant, mal einen Einblick in den Workflow “fremder” Projekte werfen zu können!
    Was machst du eigentlich, wenn der patch, den du zurückportierst, nicht passt, es also Probleme beim Anwenden gibt weil der Code schon geändert wurde?
    Ich freue mich auch schon auf die finale KDE SC 4.4 Sieht bisher schon fantastisch aus, ist hin und wieder aber noch instabil.

    1. Was machst du eigentlich, wenn der patch, den du zurückportierst, nicht passt, es also Probleme beim Anwenden gibt weil der Code schon geändert wurde?

      Kommt drauf an. Im besten Fall ist es einfach nur die Zeilennummer verschoben – dann läuft der Patch trotzdem durch. Wenn nicht, dann kommt es auf die Wichtigkeit drauf an. Bei einem sehr seltenen Problem würde ich es wohl ignorieren. Oder halt anpassen. Dafür muss man dann aber auch ein build environment noch haben. So kann ich aktuell für 4.3 keinen Code mehr testen, da mir das build environment fehlt.

      1. Sowas habe ich mir schon gedacht… und dann meckern die Nutzer wieder über Regressionen.
        Noch eine Frage habe ich: Git ist ja grade für solche Dinge (Patches über mehrere Zweige) hervorragend geeignet. – Warum setzt KDE noch nicht auf Git? Klar, eine Migration ist immer aufwändig, aber die Vorteile von Git sind ja auch enorm…

        Sorry für meine Neugier :)

  3. Interessanter Bericht. Eine Frage liegt mir auf der Zunge: Warum wird ein Bug nicht in der Version gefixt, für die er gemeldet wurde und dann nach oben gemerget? Also gefixt in 4.3 und dann mit 4.4 und dann mit trunk.

    Ich könnte mir vorstellen, das so die Stabilität des Releases erhöht würde, weil Merges ja immer mit Gefahren verbunden sind, zumal wenn sie automatisiert geschehen.

    1. Die Entwicklung findet halt immer in trunk statt. D.h. primäres Ziel ist es Verbesserungen in trunk einzubauen. Wenn dadurch gleichzeitig ein Problem in einem Release behoben werden kann: um so besser.

      Nicht alle Probleme können in den branch zurückportiert werden, da es manchmal z.B. einen neuen GUI String erfordert.

Comments are closed.