Um der Sache auf den Grund zu gehen, sehen wir uns zunächst die Werte aller lokalen Variablen an mit ''info locals''. U.a. sehen wir, daß
I = 1
LL = -2147091208
L = 86
Der Wert für LL ist merkwürdig, denn LL sollte von 1 bis N laufen, und
mit ``print N'' überzeugen wir uns von
N = 100
Um uns anzusehen, wann LL diesen seltsamen Wert bekommt, setzen wir einen
''Tracepoint'' an den ersten Befehl der LL-Schleife (Z.65), d.h. wir wollen
jedesmal, wenn diese Stelle passiert wird, einige Informationen erhalten.
Wir definieren dazu:
trace line 65 {echo/n "Zeile 65: LL = "; print LL; resume;}
Damit werden jedesmal, wenn diese Stelle passiert wird, die Kommandos in
den geschweiften Klammern ausgeführt, d.h. es wird - ohne anschließendes
Newline - ein Text ausgegeben (echo/n), dann der Wert der Variablen LL
angezeigt (print), und schließlich mit der Programm-Ausführung
fortgefahren (resume). Ohne ''resume'' würde bei Erreichen des Tracepoint
das Programm angehalten. Der Tracepoint wird durch ein Symbol im
Source-Fenster angezeigt.
Wir starten das Programm nun neu mit dem Kommando ''run''. Da das Programm vom letzten Lauf noch aktiv ist, fragt CXdb nach, ob der entsprechende Prozeß abgebrochen werden soll. Wir antworten mit ''y'' für ja. Als Ergebnis des Trace erhalten wir:
Zeile 65: LL = (INTEGER*4) 1
Zeile 65: LL = (INTEGER*4) 2
Zeile 65: LL = (INTEGER*4) 3
Zeile 65: LL = (INTEGER*4) 4
Danach erscheint wieder die alte Fehlermeldung. Daraus folgt, daß sich
zwischen dem Tracepoint (Z.65) und dem Fehler (Z.69) der Wert von LL
geändert hat, obwohl dort nur die Variablen DUM und A auftauchen. Wir
sehen uns den Inhalt von A an mit ``print A''. CXdb gibt standardmäßig
maximal 20 Werte eines Arrays auf einmal aus, in unserem Fall also nur den
Anfang der ersten Zeile. Aber auch hier sieht man schon, daß darunter
gigantisch große Zahlen sind, obwohl A am Anfang nur Zufallszahlen
zwischen -1 und 1 enthalten soll. Mehrere Ursachen sind denkbar:
break routine LINALG
Nach ''run'' (und der üblichen Abfrage) bleibt das Programm in Zeile 46 von
main.f , der ersten ausführbaren Zeile, stehen. Der Breakpoint wird im
Source-Fenster durch ein ''B'' vor der Zeile angezeigt. Mit den Kommandos
''step'' und ''next'' kann man nun in Einzelschritten durch das Programm gehen,
wobei ''next'' einen Unterprogramm-Aufruf als einen Schritt ansieht und
komplett ausführt, während ''step'' in das Unterprogramm hineingeht. Mit
zwei next-Schritten führen wir die Routine GETVEC aus und sehen uns mit
''print A'' die ersten 20 Werte von A an: Sie liegen alle im richtigen
Bereich. Mit drei weiteren next-Kommandos gehen wir bis vor den Aufruf von
GAUSSJ. Die Werte von A sind erwartungsgemäß unverändert. Nun gehen wir
mit ''step'' in die Routine GAUSSJ hinein. ''print A'' zeigt, daß jetzt A
falsche Werte hat, es wird also nicht richtig an GAUSSJ übergeben. Mit
''info args'' erhalten wir Informationen über die Argumente von GAUSSJ;
insbesondere sehen wir, daß A hier den Typ
PAUSE: SINGULAR MATRIX
Wir starten wieder den Debugger mit ''cxdb linalg'' und das Programm selbst
mit ''run''. Das Proceß-Fenster erscheint mit der PAUSE-Zeile und einer
Eingabe-Einforderung. Wir antworten aber nicht dort - das wurde den Prozeß
beenden -, sondern im Command-Fenster mit ''Control-c'', um den Prozeß
anzuhalten. Das Source-Fenster zeigt die augenblickliche Position an: Das
Programm steht in GAUSSJ in Zeile 41. Um zu sehen, warum die IF-Abfrage in
Z.40 erfüllt wurde, sehen wir uns mit ''info locals'' die entsprechenden
Variablen an:
K = (INTEGER*4) 51
IPIV = INTEGER*4(1:50) 0x8004c040
Der Fehler ist diesmal leicht zu finden: IPIV ist deklariert als
50-elementiges Feld, aber in Zeile 40 wird IPIV(51) abgefragt. Der Wert von
K geht auf die Schleife in Z.33-43 zurück, in der K von 1 bis N=100
läuft. IPIV dagegen ist über den Parameter NMAX=50 deklariert.
![]()