Ein wesentlicher Anteil der Arbeitszeit bei der Softwareentwicklung ist der Fehlersuche gewidmet – daher ist ein guter Debugger ein essentielles Werkzeug. Das meistgenutzte freie Werkzeug ist sicher der Kommandozeilen-Debugger GDB, der auch bei vielen IDEs als Backend verwendet wird. Neben freien Werkzeugen bietet das URZ dafür auch die kommerzielle Software Totalview an. Diese bietet einige Funktionalitäten, welche die Produktivität deutlich steigern können.
Visualisierung komplexer Datenstrukturen
Moderne C++-Software verwendet in großem Umfang Template-Datenstrukturen, in der Regel aus der C++-Standardbibliothek. Bei größeren Datenstrukturen und Datenmengen sind grafische Debugger generell vorteilhaft, um diese übersichtlich darzustellen. Bei Totalview werden Datenstrukturen in der üblichen Baumdarstellung angezeigt, in der die interessanten Teile gezielt geöffnet werden. Damit gelingt die Erkundung beliebig komplexer Datenstrukturen problemlos. Dieser Aspekt sollte eigentlich selbstverständlich sein – tatsächlich stoßen aber viele Programme an ihre Grenzen, wenn Container-Klassen verschachtelt und zu komplexen Datenstrukturen zusammengesetzt werden. GDB selbst benötigt bereits ein Plugin, um diese Container-Klassen überhaupt gut leserlich darzustellen.
Bei großen Datenmengen ist die Übersicht über die Informationen eine zusätzliche Herausforderung. Totalview verfügt hier über bereits eingebaute Methoden um Daten zu filtern, zu akkumulieren und zu visualisieren. Bei anderen Werkzeugen ist hier häufig zusätzlicher Programmieraufwand nötig.
Reverse Debugging
Der Zeitpunkt, zu dem sich ein Programm fehlerhaft verhält, ist oft einfach zu detektieren – im einfachsten Fall ist es ein Programmabsturz. Die Frage ist dann immer: Wie konnte es dazu kommen? Wie konnte diese Variable diesen Wert haben oder diese Datenstruktur korrupt sein? Debugging ist prinzipiell ein rückwärts gerichteter Prozess, bei den es darum geht, die Abfolge der Ereignisse, die letztlich zum fehlerhaften Programmverhalten führen, zu ihrem Anfang zurückzuverfolgen.
Im Verlauf der Fehlersuche wird dabei das Programm oft mehrfach gestartet oder in einen früheren Zustand zurückgesetzt, um die Fehlerquelle einzukreisen. Ein viel effizienteres Vorgehen wäre aber, wenn man das Programm von der Fehlerstelle aus rückwärts laufen lassen könnte. Diese als Reverse Debugging bezeichnete Methode ist eine zentrale Funktionalität von Totalview. Für jeden der bekannten Schritte des Vorwärts-Debugging gibt es eine entsprechende Variante des Reverse Debugging. Die entsprechenden Schaltflächen befinden sich gleichberechtigt neben den üblichen Funktionen für Vorwärts-Debugging. Um das Reverse Debugging zu verwenden, muss zunächst die dahinter liegende ReplayEngine aktiviert werden. Damit geht ein erheblicher Speicheraufwand und Laufzeit-Overhead einher (nach eigener Erfahrung in der Regel Faktor 2 bis 10). In den meisten Fällen ist dies aber verkraftbar und wird durch die erhebliche Zeitersparnis bei der Fehlersuche aufgewogen.
Zum Vergleich: Auch in GDB ist Reverse Debugging seit Version 7.0 enthalten. Allerdings ist der Laufzeit-Overhead deutlich höher (bei einigen Tests bis zu Faktor 50000), was den Einsatz stark eingeschränkt. Bei grafischen Frontends wird es oft regelrecht versteckt – es existiert meist keine Unterstützung durch die grafische Oberfläche.
Nach der eigenen Nutzungserfahrung ist diese effiziente und gut zugängliche Umsetzung von Reverse Debugging ein wesentlicher Vorteil von TotalView gegenüber den meisten anderen Werkzeugen, insbesondere GDB und darauf aufbauenden Frontends und IDEs.
Paralleles Debugging
Moderne Programme arbeiten praktisch immer parallel, um die Kapazitäten von Mehr-Kern-CPUs oder Rechen-Clustern zu nutzen. Dabei werden manchmal mehrere Prozesse (z. B. MPI), manchmal mehrere Threads oder auch eine Kombination verwendet. Typische Fehlerquellen sind dabei die Kommunikation und die zeitliche Abfolge. Bei der Verwendung von GDB ist eine verbreitete Methodik, eine Instanz von GDB an jeden Thread anzuheften – ein Verfahren, das offensichtlich einen deutlichen Mehraufwand erzeugt und schlecht skaliert. Von grafischen Frontends wird paralleles Debugging häufig kaum unterstützt.
Bei Totalview werden alle beteiligten Prozesse und Threads eines Programms automatisch in der gleichen Instanz des Debuggers gestartet. Jeder davon kann beliebig angehalten, inspiziert und fortgesetzt werden. Es ist aber auch möglich, alle Threads eines Prozesses oder alle Prozesse gemeinsam anzuhalten und fortzusetzen. Als dritte Organisationsstufe können benutzerdefinierte Gruppen gebildet werden. Sämtliche Einstellungen (z. B. Breakpoints, beobachtete Variablen) können separat für einen Thread, aber auch für größere Gruppen getroffen werden. Damit kann auch bei umfangreicher Parallelisierung präzise gesteuert werden, welche Programmteile unter welchen Bedingungen gestoppt werden.
Eine klare Synergie ergibt sich dabei mit dem genannten Reverse Debugging: Fehler durch parallele Programmierung sind oft von scheinbar zufälligen Reihenfolgeeffekten abhängig und schwer zu reproduzieren. Mit Hilfe von Reverse Debugging reicht es oft, einen Fehler nur einmal im Debugger zu reproduzieren, um ihn von dort zu seiner Ursache zurückzuverfolgen.
Memory Debugging
Totalview besitzt mit dem Modul MemoryScape ein eigenes Werkzeug, um Fehler wie Speicherlecks oder Zugriffe auf nicht initialisierte Speicherbereiche zu detektieren. Beispielsweise kann für jeden Speicherblock analysiert werden, an welcher Stelle dieser angefordert wurde (siehe Screenshot). Im Vergleich zu dem weit verbreiteten Standardwerkzeug Valgrind fällt hier vor allem die deutlich bessere Performance auf. Der Laufzeit-Overhead beträgt bei den Standardeinstellungen lediglich etwa Faktor 2 – bei Valgrind fällt dieser bei vergleichbarer Analysetiefe erfahrungsgemäß deutlich höher aus. Die grafische Oberfläche von MemoryScape ist dabei sehr hilfreich, um auch bei größeren Datenmengen den Überblick zu behalten.
Totelview ist an der TU Chemnitz vorhanden. Sollte bei Ihnen Interesse bestehen, Totalview selbst einmal zu testen, können Sie an support@hrz.tu-chemnitz.de schreiben und Zugang zur Software erhalten.
Schreibe einen Kommentar
Du musst angemeldet sein, um einen Kommentar abzugeben.