C Source Debugger: Ein zuverlässiger Kammerjäger

Nicht nur C-Programmierer wissen, wie schnell sich Fehler in ein Programm einschleichen. C läßt dem Programmierer sehr viele Freiheiten: Er darf Array-Bereiche ignorieren, in Betriebssystem-Vektoren sein Unwesen treiben, ohne daß der C-Compiler murrt. Ein C-Kenner schrieb treffend: In C programmieren ist so sicher, wie eine Handgranate in Nitroglyzerin baden. Beliebte »Wanzen«, wie ein vergessenes Gleichheitszeichen oder ein falsch indiziertes Array schlüpfen anstandslos durch jeden konventionellen C-Compiler und gestalten so das Programmieren zu einem echten Abenteuer für den Programmierer. Nur ein ANSI-C-Compiler führt eine weitergehende Fehlerprüfung durch — aber auch die ist nicht immer erfolgreich. Auf der Suche nach solchen Fehlern spaltete sich die Gemeinde der C-Programmierer in zwei Lager. Zum einen gibt es die fleißigen »Printfler«, die an jeder strategischen Stelle des Programms mittels »printf()« Variablenwerte ausgeben (eng verwandt mit den »Writeln’em« aus der Wirth-schen Programmierschule). Auf der anderen Seite die »echten« Programmierer, die nur mit ihrem Lieblings-Disassembler und — wenn überhaupt — mit einer Symboltabelle glücklich sind. Der wesentlich angenehmere und effizientere Weg ist die Benutzung eines sogenannten Quelltext-Entwanzers — manche sagen auch »Sourcecode-Debugger«. Der konfrontiert den Programmierer nicht mit der harten Assembler-Realität — »Ah, das hier könnte meine for-Schleife sein« —, sondern zeigt den Quelltext des Programms. Benutzern von Mark Williams C steht so ein Dienstbote zur Seite: der »C Source Debugger« von Mark Williams, kurz CSD genannt.

Zum Lieferumfang des CSD gehört eine einseitig formatierte Diskette sowie ein rund 100 Seiten dickes, gebundenes Handbuch. Die Installation des CSD ist dank des mitgelieferten GEM-gesteuerten Installationsprogramms denkbar einfach und trotzdem sehr flexibel. Anhand einer Beispielsitzung führt das Handbuch den Anfänger in die Bedienung ein. Den fortgeschrittenen Anwender unterstützt eine Befehlsreferenz und ein Stichwortregister.

In den Genuß des CSD kommen allerdings nur Benutzer von Mark Williams C 3.0 (siehe Test in der Ausgabe 9/88) die ihre Programme mit der neuesten Compilerversion unter der Option »-VCSD« compiliert haben. Dabei holt der Compiler die für den Debugger notwendigen Informationen über Variablen und Zeilennummern und auch die Namen der verwendeten Quelldateien in die Symboltabelle des Programms. Die Menge der hier übermittelten Informationen zeigt sich deutlich an der Größe des Compilats: Der Editor »Gnome«, zuvor 54 KByte groß, schwillt auf 170 KByte an. Doch wenn man die vielfältigen Funktionen des CSD betrachtet, so ist dies nur zu verständlich. Der CSD kann auch GEM-Anwendungen unter die Lupe nehmen, weil er selbst GEM nicht nutzt. Er reserviert sich eigene Bildschirmseiten, um die Daten anzuzeigen, und zerstört somit auch nicht den Bildschirmaufbau des zu untersuchenden Programms. Dem Benutzer stehen unter CSD vier verschiedene »Windows« zur Verfügung, zwischen den er mit den Funktionstasten < F7 > bis < F10 > umschaltet:

Nach seinem Start präsentiert sich der Debugger mit der Anzeige von Source-Window und Evaluation-Window auf einer gemeinsamen Bildschirmseite.

In diesem Teil des CSD ist eine abgespeckte Version des Editors »Micro-Emacs« eingebaut, der auch als Programmeditor zum Lieferumfang des Mark Williams C-Compilers gehört. Editorfunktionen wie Blättern, Scrollen und Suchen von beliebigen Textpassagen arbeiten somit auch im Source-Window und im Evaluation-Window. Egal wie groß ein Schreibtisch ist, der Platz reicht nicht aus. Die Entwickler des CSD haben deswegen ihr Produkt ausreichend mit Hilfsmenüs versehen. Das Handbuch benötigt man nach den ersten Anwendungen kaum noch. Über die Help-Taste sind sämtliche Menüs erreichbar. Besteht ein Befehl aus mehreren Tastaturkommandos, so gibt der CSD dem Anwender intelligente Hilfe, indem er die momentan sinnvollen Tastenkombinationen auf dem Bildschirm anzeigt. Dazu gehört auch immer die Help-Taste, über die man automatisch in das richtige Hilfsmenü gelangt.

Der eingebaute MicroEmacs ist leider etwas zu intelligent. Er paßt sich automatisch an die aktuelle Bildschirmauflösung an und richtet sein Editorfenster entsprechend ein. Dies führt kurioserweise dazu, daß der Bildschirmaufbau des CSD in der niedrigen Auflösung durcheinandergerät. Der Debugger schaltet nämlich bei eigenen Ausgaben in die mittlere Auflösung und benutzt 80 Zeichen pro Zeile. Der MicroEmacs nutzt jedoch nur die Hälfte. Dies sieht nicht schön aus, beeinträchtigt den CSD ansonsten aber nicht.

Mittels < F3 > kann man an jeder Zeile im Quelltext, die einen ausführbaren C-Ausdruck enthält, einen Tracepoint setzen. CSD zeigt solche Zeilen danach fett gesetzt an. Tracepoints erfüllen zweierlei Funktion: Zum einen gibt CSD an solchen Stellen bei der Ausführung des Programms eine Meldung im History-Window aus. So erkennt man einfach, wann und wie oft bestimmte Ausdrücke abgearbeitet werden. Auf Wunsch behandelt der Debugger diese Stellen auch als »Breakpoint« — das Programm stoppt an solchen Punkten. Wie der Debugger Tracepoints behandelt, legt man beim Start eines Programms fest. Hier zeigt sich der CSD von seiner flexibelsten Seite. Mittels < F4 > wählt man zwischen folgenden Funktionen:

Normalerweise aktiviert der CSD bei der Ausführung eines Programms das Program-Window und schaltet danach wieder in das Source-Window zurück. Aber auch alle anderen Fenster kann man sich anzeigen lassen — wenn man zum Beispiel den aktuellen Quelltext immer vor Augen haben will.

Der interessanteste Tfeil des CSD ist zweifellos das Evaluation-Window, in dem man jeden gültigen C-Ausdruck auswerten kann, angefangen von Zuweisungen an Variablen bis hin zu kompletten Funktionsaufrufen. Hier zeigt sich die große Flexibilität des Debuggers. Variablen und Funktionen spricht man unter ihrem Namen an, das lästige Herumhantieren mit Adressen entfällt. Auch lokale Variablen der Funktion, in der man sich gerade befindet, sind ansprechbar. Gerade diese findet man mit einem konventionellen Debugger nur mit großer Mühe auf dem Stack.

CSD erkennt auch den Datentyp jeder Variablen: »ints« gibt er dezimal, »floats« als Gleitkommazahl und »chars« als ASCII-Zeichen aus. Ebenso einfach greift man auf einzelne Elemente von »structures« und »unions« zu. Gibt man nur den Namen einer Structure an, so zeigt er deren Inhalt hexadezimal an. Ein Pointer enthält für ihn eine hexadezimale Adresse. Pointer auf Chars derefe-renziert man durch ein vorangestelltes »(str)«.

Ebenso sind die Wertzuweisungen typgebunden. Leider besitzt CSD keine Informationen über die Arbeit des C-Präprozessors. So kann man keine vor-definierten Konstanten oder Makros verwenden. »Enums« zeigt der Debugger nur durch deren Zahlenwerte an, obwohl die Namen in der Symboltabelle vorhanden sind. Hier wünscht man sich, auch mit der Ausgabe des Präprozessors arbeiten zu können.

Zusätzlichen Komfort liefert das Tracen von Ausdrücken. Darunter versteht CSD zweierlei. Im Single-Step-Modus zeigt er vor der Ausführung einer Zeile den aktuellen Wert eines solchen Ausdrucks an. Andererseits kann er ein Programm genau dann anhalten, wenn sich dieser Wert ändert. Somit kann man »Watchpoints« setzen, das heißt, CSD unterbricht zum Beispiel die Programmausführung, wenn eine Variable einen bestimmten Wert überschreitet.

Eine riesengroße Hilfe ist das »Wandern« durch die Funktionsaufrufe. Hat CSD das Programm in einer Funktion gestoppt, so kann man mit den Pfeiltasten durch die aufrufenden Funktionen blättern. Die lokalen Variablen der aufrufenden Funktion sind für die aufgerufene nicht sichtbar, existieren aber auf dem Stack und haben daher auch einen gültigen Wert. Wandert man einen Funktionsaufruf »hinauf«, so kann CSD diese Variablen im Evaluation-Window verarbeiten. Mit der rechten Pfeiltaste geht man wieder ein Stufe hinunter. Jeder, der schon einmal einen Fehler in einer Kette sich gegenseitig aufrufender Funktionen gehabt hat, weiß diese Funktion zu schätzen. Selbstverständlich, daß CSD die Exceptions des 68000ers, wie Adreß-und Busfehler, abfängt, und an die entsprechende Stelle im Quelltext verweist. Bei so einem Fehler wäre es allerdings günstig, wenn der CSD auf Wunsch auch den Assembler-Code anzeigen würde. Zwar gibt er ausführliche Informationen über die Registerinhalte, aber er hilft nicht, wenn man nicht weiß, welches Register welcher Variable entspricht. Hier zeigt sich ein Fehler im Debugger. Greift der CSD auf eine Adresse um $FFxxxx zu, so stürzt er mit der Fehlermeldung »Internal stack overflow« ab, und nur der Resetknopf belebt den ST wieder.

Etwas umständlich ist das Debuggen großer Programme, die aus mehreren Quelltexten bestehen. CSD lädt die Sourcefiles in der Reihenfolge, wie sie gelinkt wurden. Geht man mit dem Cursor über das Ende eines Quelltextes hinaus, erscheint der folgende. Auch die Textsuche ist auf das aktuelle Sourcefile beschränkt. Bei all dem Komfort, den der CSD ansonsten zu bieten hat, ist diese Unzulänglichkeit nur schwer einzusehen.

CSD macht selbst bei großen Programmen keine Fehler. Nur ist leider nirgendwo vermerkt, daß in dem Datenbereich, den der CSD sich intern anlegt, auch das zu untersuchende Programm Platz finden muß. Die normale Größe dieses Bereichs, 128 KByte, läßt sich allerdings leicht verändern — dafür gibt es eine Funktion in der Kommandozeile.

Der CSD debuggt auch Programme, bei denen nur einzelne Quelltexte mit der Option »-VCSD« compiliert wurden. Die hilft, Programme klein zu halten.

Der C Source Debugger von Mark Williams ist ein solides Stück Software. Durch seine vielfältigen Funktionen ist er vor allen Dingen dem C-Neuling, der sich vom Compiler oft allein gelassen fühlt, ein große Hilfe. Die mächtigen Funktionen und das gute Konzept gleichen die im Test beschriebenen Schwächen bei weitem aus. Für den Profi bleibt zu hoffen, daß der Komfort beim Debuggen großer Programme noch gesteigert wird. So ein Debugger sollte für alle Compiler erhältlich sein. (ps/uh)

Markt & Technik Verlag AG, Hans- Pinsel-Str. 2, 8013 Haar

Wertung

Produktname: C Source Debugger
Preis: 149 Mark
Hersteller: Mark Williams

Stärken:
□ Auswerten von beliebigen C-Ausdrücken □ viele Debugging-Fähigkeiten □ Trace-, Break- und Watchpoints □ gute Online-Hilfe

Schwächen:
□ geringer Komfort bei mehreren Quelltexten □ funktioniert in der nie-drigen Auflösung nicht einwandfrei

Fazit: ein guter Source-Debugger, der nicht nur dem C-Neuling eine große Hilfe ist


Julian F. Reschke Stefan Eissing
Aus: ST-Magazin 11 / 1988, Seite 36

Links

Copyright-Bestimmungen: siehe Über diese Seite