ctrace(1) ctrace(1)
NAME
ctrace - Debugger für C-Programme
SYNTAX
ctrace [Option...] [Datei]
BESCHREIBUNG
Mit dem Kommando ctrace wird ein C-Programm für die Ablaufverfolgung
zur Laufzeit vorbereitet. Die Auswirkung ist ähnlich wie bei der Aus-
führung einer Shell-Prozedur mit der Option -x. ctrace liest das C-
Programm aus Datei oder von der Standardeingabe, wenn Datei nicht
angegeben wurde. Jeder ausführbaren Anweisung werden weitere Anweisun-
gen hinzugefügt, die zur Laufzeit den Text dieser ausführbaren Anwei-
sung sowie den Wert aller von ihr veränderten oder referenzierten
Variablen ausgeben. ctrace schreibt das modifizierte Programm auf die
Standardausgabe. Die Ausgabe von ctrace muß in eine temporäre Datei
geschrieben werden, weil das Kommando cc(1) die Verwendung von Pipes
nicht zuläßt. Anschließend kann diese Datei dann übersetzt und ausge-
führt werden.
Jede Anweisung im Programm wird während ihrer Ausführung auf dem Bild-
schirm aufgelistet. Anschließend werden Name und Wert der Variablen
angezeigt, auf die in der Anweisung verwiesen wurde oder die verändert
wurden, und danach folgt die ggf. von diesem Statement veranlaßte Aus-
gabe. Schleifen in der Ablaufverfolgung werden festgestellt, und die
Ablaufverfolgung wird gestoppt, bis die Schleife verlassen oder eine
andere Anweisungsreihenfolge innerhalb der Schleife ausgeführt wird.
Bei jedem tausendsten Durchlaufen der Schleife wird eine Warnung aus-
gegeben, um dem Benutzer zu helfen, unendliche Schleifen zu entdecken.
Die Ausgabe der Ablaufverfolgung wird auf die Standardausgabe
geschrieben, die in eine Datei umgelenkt werden kann, damit der Benut-
zer diese mit Hilfe eines Editors oder anderer Kommandos untersuchen
kann.
OPTIONEN
Normalerweise werden folgende Optionen eingesetzt:
-f Funktionen nur den Ablauf dieser Funktionen verfolgen
-v Funktionen außer diesen Funktionen den Ablauf aller Funktionen ver-
folgen
Die Standardformate für die Ausgabe von Variablen können ergänzt wer-
den. Variablen vom Typ long und Zeiger-Variablen werden immer als
ganze Zahlen mit Vorzeichen ausgegeben. Zeiger auf Zeichenfelder wer-
den auch als Zeichenketten ausgegeben, wenn dies sinnvoll ist. char-,
short- und int-Variablen werden ebenfalls als ganze Zahlen mit Vorzei-
chen und gegebenenfalls auch als Zeichen ausgegeben. Variablen vom Typ
double werden in wissenschaftlicher Notation als Gleitkommazahlen aus-
gegeben.
Mit den folgenden Optionen kann die Ausgabe von Variablen auch in
Seite 1 Reliant UNIX 5.44 Gedruckt 11/98
ctrace(1) ctrace(1)
zusätzlichen Formaten erfolgen:
-o oktal
-x hexadezimal
-u vorzeichenlos
-e Gleitkomma
Diese Optionen werden nur unter besonderen Umständen verwendet:
-l n Statt der standardmäßig vorgegebenen 20 Anweisungen n aufeinan-
derfolgend ausgeführte Anweisungen für die spezielle Schleifena-
blaufverfolgung prüfen.
Mit 0 erhält man die gesamte Ablaufverfolgung von Schleifen.
-s Die redundante Ablaufverfolgung von einfachen Zuweisungen und
Kopierfunktionen für Zeichenketten unterdrücken.
Diese Option kann einen Fehler verdecken, der durch die Anwendung
des Operators = anstelle des Operators == verursacht wird.
-t n Anstelle der standardmäßig vorgegebenen 10 Variablen (Höchstzahl
ist 20) n Variablen pro Anweisung verfolgen.
-P Den C-Präprozessor vor der Ablaufverfolgung ausführen.
Die Optionen -D, -I und -U von cc(1) sind ebenfalls verwendbar.
-p Zeichenkette
Die Ausgabefunktion für die Ablaufverfolgung umdefinieren (Stan-
dard: printf).
Zum Beispiel wird mit fprintf(stderr) die Ablaufverfolgung auf
die Standardfehlerausgabe geschrieben.
-r f Die Datei f anstelle des runtime.c-Laufzeit-Überwachungspaketes
verwenden
Mit dieser Option läßt sich die gesamte Ausgabefunktion ändern,
nicht nur der Name und die führenden Argumente (siehe -p).
-V Auf Standardfehlerausgabe Informationen über die Version von
ctrace ausgeben.
-Q Arg
Wenn Arg gleich y ist, werden zu den Ausgabedateien Informationen
zur Identifikation von ctrace hinzugefügt. Das kann zur Software-
verwaltung sinnvoll sein. Bei der Angabe von n für Arg wird
explizit angegeben, daß solche Informationen nicht benötigt wer-
den. Das ist das Standardverhalten.
Seite 2 Reliant UNIX 5.44 Gedruckt 11/98
ctrace(1) ctrace(1)
BEISPIEL
Die Datei lc.c enthält das folgende fehlerhafte C-Programm:
1 #include <stdio.h>
2 main() /* Zeilen in der Eingabe zählen */
3 {
4 int c, nl;
5
6 nl = 0;
7 while ((c = getchar()) != EOF)
8 if (c = '\n')
9 ++nl;
10 printf("%d\n", nl);
11 }
Geben Sie folgende Kommandos und Testdaten ein:
cc lc.c
a.out
1
(^d)
Das Programm wird übersetzt und ausgeführt. Die Ausgabe des Programms,
die Zahl 2, ist falsch, weil in den Testdaten nur eine Zeile vorhanden
ist. Dieser Programmierfehler ist weit verbreitet, aber oft schwer zu
finden. Wird ctrace mit diesen Kommandos aufgerufen:
ctrace lc.c >temp.c
cc temp.c
a.out
dann ist die Ausgabe:
2 main()
6 nl = 0; /* nl == 0 */
7 while ((c = getchar()) != EOF)
Das Programm wartet nun auf die Eingabe. Werden dieselben Testdaten
wie vorher eingegeben, ist die Ausgabe wie folgt:
/* c == 49 or '1' */
8 if (c = '\n')
/* c == 10 or '\n' */
9 ++nl; /* nl == 1 */
7 while ((c = getchar()) != EOF)
/* c == 10 or '\n' */
8 if (c = '\n')
/* c == 10 or '\n' */
9 ++nl; /* nl == 2 */
7 while ((c = getchar()) != EOF)
Wird nun ein Dateiende-Zeichen <CTRL-D> eingegeben, ist die endgültige
Seite 3 Reliant UNIX 5.44 Gedruckt 11/98
ctrace(1) ctrace(1)
Ausgabe:
/* c == -1 */
10 printf("%d\n", nl);
/* nl == 2 */2
return
Beachten Sie die Ausgabe am Ende der Kontrollausgabe für die Variable
nl nach Zeile 10. Beachten Sie weiterhin den von ctrace eingefügten
Kommentar return. Damit wird die implizite Rückkehr an der schließen-
den Klammer in der Funktion angezeigt.
Die Ausgabe der Ablaufverfolgung zeigt an, daß der Variablen c in
Zeile 7 der Wert 1 zugewiesen wird, sie in Zeile 8 jedoch den Wert \n
hat. Nachdem der Benutzer auf diese if-Anweisung hingewiesen worden
ist, wird er erkennen, daß der Zuweisungsoperator = statt des Gleich-
heitsoperators == verwendet wurde. Dieser Fehler kann leicht beim
Lesen des Codes übersehen werden.
Steuerung der Ablaufverfolgung zur Ausführungszeit
Die Standardfunktion von ctrace besteht in der Ablaufverfolgung des
gesamten Programmes, sofern nicht die Optionen -f oder -v zur Ablauf-
verfolgung bestimmter Funktionen eingesetzt werden. Der Benutzer
erhält dadurch jedoch keine Möglichkeit den Ablauf einzelner Anweisun-
gen zu verfolgen; auch läßt sich die Ablaufverfolgung nicht während
der Programmausführung ein- oder abschalten.
Jedoch kann man durch Einfügen der Funktionsaufrufe ctroff() und
ctron() in das Programm die Ablaufverfolgung während der Ausführungs-
zeit ein- bzw. abschalten. Auf diese Weise kann man beliebig komplexe
Kriterien mit if-Anweisungen für die Steuerung der Ablaufverfolgung
zur Ausführungszeit aktivieren und diesen Code sogar bedingt einfügen,
weil ctrace die Präprozessor-Variable CTRACE definiert.
Die Ablaufverfolgung läßt sich auch durch Setzen der statischen Varia-
blen trct auf 0 bzw. 1 ein- und abschalten. Dies ist nützlich, wenn
ein Debugger eingesetzt wird, der diese Funktionen nicht direkt aufru-
fen kann.
DIAGNOSE
Dieser Abschnitt enthält Diagnosemeldungen von ctrace und cc(1), da
das Protokoll der Ablaufverfolgung oft cc-Warnungen erhält.
warning: some variables are not traced in this statement
Nur 10 Variablen werden in einer Anweisung verfolgt, um den C-
Übersetzer-Fehler "out of tree space; simplify expression" zu
vermeiden. Diese Zahl wird mit der Option -t erhöht.
warning: statement too long to trace
Seite 4 Reliant UNIX 5.44 Gedruckt 11/98
ctrace(1) ctrace(1)
Diese Anweisung ist über 400 Zeichen lang. Achten Sie darauf, daß
zum Einrücken des Codes Tabulatoren und nicht Leerstellen verwen-
det werden.
cannot handle preprocessor code, use -P option
Diese Meldung wird gewöhnlich von den Präprozessor-Anweisungen
#ifdef/#endif in der Mitte einer C-Anweisung oder von einem Semi-
kolon am Ende einer Präprozessor-Anweisung #define verursacht.
'if ... else if' - sequence too long
Teilen Sie die Sequenz durch Entfernen eines else aus der Mitte
auf.
possible syntax error, try -P option
Bearbeiten Sie zuerst die ctrace-Eingabe mit der Option -P und
geeigneten Präprozessor-Optionen -D, -I und -U.
HINWEISE
Wird eine Funktion mit demselben Namen wie eine Systemfunktion defi-
niert, kann das bei einer Änderung der Anzahl der Argumente einen Syn-
taxfehler hervorrufen. Benutzen Sie einfach einen anderen Namen.
ctrace nimmt an, daß BADMAG ein Präprozessor-Makro ist und daß EOF und
NULL mit #define definierte Konstanten sind. Wenn eine von ihnen als
Variable erklärt wird, z. B. "int EOF;", entsteht dadurch ein Syntax-
fehler.
Zeiger werden immer wie Zeiger auf Zeichenketten behandelt.
ctrace kennt keine Komponenten eines Verbunds, wie z. B. Strukturen,
Unions und Felder. Wenn eine Zuweisung an den gesamten Verbund
erfolgt, werden nicht alle einzelnen Komponenten ausgegeben. ctrace
kann sich in diesem Fall für die Ausgabe der Adresse des Verbundes
entscheiden oder das falsche Format verwenden (z. B. 3.149050e-311 für
eine Struktur mit zwei ganzzahligen Teilen), wenn der Wert eines Ver-
bunds ausgegeben wird. Die Eliminierung der Ausgabe einer Schleifen-
verfolgung erfolgt separat für jede Datei eines Mehrdateien-Programms.
Dies kann dazu führen, daß Funktionen von einer Schleife aufgerufen
werden, die noch verfolgt wird, oder daß die Ablaufverfolgung einer
Funktion in einer Datei unterdrückt wird, bis eine andere Funktion in
derselben Datei aufgerufen wird.
DATEIEN
/usr/lib/ctrace/runtime.c
Laufzeit-Überwachungspaket
SIEHE AUCH
bfs(1), tail(1), ctype(3C), string(3C), fclose(3S), printf(3S).
Seite 5 Reliant UNIX 5.44 Gedruckt 11/98