Freebasic- das SDK: FBIDE, Editoren, FBC, GDB


Informationen beschaffen und Freebasic-Paket herunterladen

Ich habe nun das Schlagwort "Freebasic" genannt. Wie kommen wir nun an Informationen darüber und an die Software selbst heran?

Ein guter Ausgangspunkt für so etwas ist immer das freie Lexikon www.wikipedia.de

. Dort stehen im Freebasic-Artikel unten zwei Links auf die deutsche und englischsprachige "Heimatseite" von Freebasic. Die deutsche besuchen wir mal: www.freebasic-portal.de.

Über "Download", Aktuelle Compiler kommen wir auf eine Seite, auf der zuoberst der aktuellste Windows-Compiler steht. Etwas weiter unten auch eine Version für Linux. (Fast alle weiteren Ausführungen in diesem und den folgenden Kapiteln lassen sich unter beiden Betriebssystemen nachvollziehen.) Wählen Sie die höchste, also aktuellste Version und gehen Sie rechts auf DOWNLOAD. Starten Sie die Installationsdatei. Keine weiteren Besonderheiten ansonsten - ausser, daß Sie sich den Installationspfad merken (oder ihn wiederfinden können) sollten.

Das war's allerdings noch nicht ganz. Damit haben wir erst den Compiler. Wir wollen aber auch wieder eine Entwicklungsumgebung haben. Die bekommen links unter "IDEs". Es werden mehrere angeboten. Ich empfehle für den Anfang FBIDE - diese IDE ist der QBasic-IDE am ähnlichsten. Hierbei handelt es sich im eine zip-Datei. Die kann man mit kostenlosen Programmen wie Filzip oder TUGzip entpacken. Am Besten das Verzeichnis IDE ins Compilerverzeichnis verschieben. Schliesslich sollte man sich noch einen Link von FBIDE ins Startmenü und nach "Senden an" legen. (Startmenü-Verzeichnis und Sendto-Verzeichnis befinden sich unter "C:\Dokumente und Einstellungen\"

FBIDE ist nicht die beste IDE für Freebasic. Das ist eher FBEdit. Aber FBIDE ist am nächsten am qbasic-Feeling dran. Trotzdem: Wenn Sie sich ein bisschen Einarbeiten nicht schrecken lassen, dann nehmen Sie FBEdit!

Starten Sie FBIDE. Gehen Sie auf File->New. Nun können Sie Ihr erstes Freebasic-Programm eintippen. Vielleicht am Anfang einfach mal ein einfaches PRINT "Hello World!". F5 drücken - und es passiert nichts. Genauer gesagt sehen Sie je nach Geschwindigkeit Ihres Rechners ein kurzes Flimmern. Der Grund: Beim Start des Programms (F5) wird ein Konsolenfenster geöffnet, die Ausgabe getätigt und das Fenster sofort wieder geschlossen. Das Ganze dauert nur 1 Millisekunde oder so. Um das zu verhindern, muss man am Ende des Programms noch eine Anweisung hinschreiben, die das Schliessen des Fensters bis zu einem Tastendruck verhindert. "Sleep" erfüllt unseren Zweck:

? "Hello World!"
sleep

Sollte der Start Schwierigkeiten machen, dann schauen Sie mal in den Menüs unter View->Settings->Freebasic nach, ob der Compilerpfad richtig gesetzt ist.

Und jetzt lassen wir die Kiste röhren...

Schauen wir mal, ob wir wirklich ein 32-Bit- (oder 64-Bit-) System haben. In diesem dürfte es kein Problem sein, in ein einziges Array mehr als 64K Daten, sagen wir 5000K Daten?, zu stopfen:

DIM a!(1000000)

FOR i=0 TO 999999
  a!(i)=i
  IF (i MOD 1000=0) THEN PRINT i/1000
NEXT i

SLEEP

Wenn Sie dies ablaufen lassen, werden Sie erstaunt sein, wie schnell die Schleife über ihre 1 Million Runden hinwegrast. Bevor Sie danach mit dem Tastendruck das Fenster schliessen, können Sie mal in den Taskmanager gehen und sich dort den reservierten Speicher Ihres Programms anschauen. Dazu lassen Sie sich in der letzten Spalte den "virtuellen Speicher" anzeigen. Dann suchen Sie das Programm "FBIDEtemp.exe":

5 MB benutzt. Das ist doch schon was. Sowas hat's unter DOS-Zeiten nicht gegeben.

Die Benutzung von FBIDE

FBIDE ist ein Einmann-Projekt, das 2004 mit Freebasic gestartet, 2006 aber eigentlich wieder eingestellt wurde. Die Funktionalität hinkt noch stark hinter den professionellen Tools wie KDevelop, Visual Basic, Delphi-IDE oder Eclipse hinterher. Aber immerhin gibt es etwas, was es in QBasic nicht gab: Syntax-Highlighting. Die Schlüsselwörter, Strings, Zahlen usw. werden in unterschiedlichen Farben angezeigt.

Sonstige Unterschiede zur QBasic-IDE:

Sehr praktisch ist, dass Sie mit Ctrl-M einen ganzen markierten Block auskommentieren können. Mit Shift-Ctrl-M wird er wieder entkommentiert.

Sie sollten sich nicht mit den Default-Settings zufriedengeben. Ich habe z.B.

Diesem Theme habe ich den Namen "qbasic" gegeben und es abgespeichert. Es steht im Freebasic-Programmverzeichnis im Unterverzeichnis IDE als Datei "qbasic.fbt", die ich überall hin mitnehmen kann.

Die Benutzung von Editoren

Ein schönes Feature von Freebasic ist, dass es nicht zur Benutzung einer bestimmten IDE zwingt. FBIDE ist nur ein Vorschlag, kein Zwang. Gerade im frühen Entwicklungsstadium von FBIDE kann es viel Sinn machen, für grössere Projekte einen anderen Editor heranzuziehen. Spätestens wenn Sie 5000 Zeilen oder mehr in der Mache haben, werden Sie bestimmte Features zu schätzen wissen:

Solche Features werden heute von zahlreichen "grossen" Editoren wie vim, Emacs, UltraEdit, SciTE, Textpad, Phase5 u.a. unterstützt. Und sie sind für gute Programmierung fast unerlässlich (es sei denn, Sie sind ein sehr schneller Schreiber). Viele Eigenheiten von BASIC sind entstanden, um dem Programmierer Schreibarbeit zu sparen. Und alle diese Eigenheiten verschlechtern den Code, machen ihn instabil und wartungsfeindlich. Ein einfaches Beispiel sind Autodeklarationen, wie wir sie bisher kannten: Einfach eine Variable benutzen, dann ist sie auch deklariert. Wer schon eimal stundenlang daran herumgerätselt hat, warum die Variable x01 an einer bestimmten Stelle null ist, obwohl sie doch ein paar Zeilen weiter oben einwandfrei mit 1 initialisiert wurde und erst nach Stunden drauf kommt, dass hier zweiVariablen existieren, weil man sich bei der Initialisierung verschrieben und statt einer Null ein O im Namen verwendet hat, der wird wissen, was ich meine. Schreibarbeit ist trotzdem nicht schön, aber das Mittel der Wahl, sie zu vermeiden, ist nicht, die Programmiersprache zu ändern, sondern einen guten Editor zu verwenden!

Entsprechend wird das nachfolgende Tutorial rigoros alles an solch zwielichtigen Sprachelementen mit Verachtung strafen und damit von Ihnen eine gewisse Schreibarbeit verlangen...

Die Benutzung des FBC

Was aber fange ich mit einem blossen Editor an? Ich möchte doch Programme kompilieren und laufen lassen! Nun, der klassische Weg ist: Source-Code im Editor schreiben und speichern, dann den Compiler von der Konsole aus aufrufen. Wenn sich das Zusammenspiel zwischen Editor und Konsole einmal eingespielt hat, ist dieser Vorgang kaum langsamer als der Druck auf F5 in FBIDE. Zur Probe erstellen Sie einmal mit einem beliebigen Editor ein kurzes QBASIC-Testprogramm, (zur Not mit Notepad, aber besser mit einem der o.g. Editoren. SciTE ist kostenlos und kann ich sehr empfehlen.) Speichern Sie das Programm als "a1.bas" im Freebasic-Programmverzeichnis. Dann gehen Sie im Dateimanager in das Freebasic-Programmverzeichnis und öffnen dort eine Konsole. Nun haben Sie die Konsole und den Editor nebeneinander. Geben Sie in der Konsole den Befehl "fbc a1.bas". Wenn Sie keinen Fehler gemacht haben, erscheint nur eine Leerzeile. Dann geben Sie den Befehl "a1" ein. Und siehe da - Ihr Testprogramm läuft! "fbc a1.bas" hat das Testprogramm kompiliert und gelinkt und ein ablauffähiges Binary "a1.exe" produziert. Ein "dir" kann Sie davon überzeugen. Der Freebasic-Compiler selbst ist also nichts anderes als ein "DOS-Befehl", ein Binary, das mit dem Quelltext im Argument aufgerufen wird.

Schreiben Sie nun weiter am Quelltext, dann können Sie wiederholte Kompilationen im Konsolenfenster einfach mittels Pfeil-oben-Taste aufrufen, da Sie hierdurch díe fbc-Befehlszeile zurückholen.

Tipp Konsolenfenster

Ihr erstes kleines Programm mag fehlerfrei durchgegangen sein, aber bei neuen Programmen, an denen Sie erstmal länger geschrieben haben, bevor Sie das erste Mal kompilieren, wird der FBC sehr viel gesprächiger sein und Sie - ich will Ihren Programmierkünsten nicht zu nahe treten - mit einer Lawine von Meldungen überrollen. Sie können es sich in so einem Fall zweifach leichter machen: Erstens, machen Sie das Konsolenfenster grösser. Klick in die linke obere Ecke des Konsolenfensters, auf "Eigenschaften", "Layout" und dort "Fenstergrösse", "Höhe" auf, sagen wir, 40 Zeilen stellen. Weiter oben können Sie der Puffergrösse gleich 1000 Zeilen geben - das schadet nichts.

Zum anderen können Sie die Ausgabe - wir haben es am Anfang von Teil II schon gelernt - von FBC in eine Datei umleiten und diese anschliessend mit dem Texteditor in aller Ruhe durchgehen. "fbc a2.bas > a.lst" leitet die Ausgabe in die Datei a.lst um.

Die Benutzung des gdb-Debuggers

"gdb" ist die Abkürzung für "GNU-Debugger". Unter "GNU" wurden die erste Familie von Open-Source-Programmen für UNIX veröffentlicht, z.B. Compiler (gcc-Suite) oder Textbearbeitungstools (GNU-sed), zu einer Zeit, als es UNIX selbst noch sehr teuer und nur dem Profilager vorbehalten war. Heute sind die GNU-Programmiertools das Herzstück der Softwareentwicklung unter Linux und haben auch eine wichtige Rolle im Windows-Bereich eingenommen. Der gdb ist kein spezifischer Debugger für Freebasic, sondern ein Debugger für alle Compiler, die sich an bestimmte Regeln und Formate beim Kompilieren halten. FBC wurde so programmiert, dass er mit gdb zusammenarbeitet.

Vorbereitung: Setzen der Pfade

Bisher haben wir unsere Testprogramme direkt ins Freebasic-Programmverzeichnis geladen - auf Dauer keine gute Idee. Für unsere Programme haben wir sicher ja ein eigenes Verzeichnis. Wie können wir von dort aus mit FBIDE, FBC, GDB usw. arbeiten? Nun, wir setzen uns den Pfad entsprechend:

Über die Systemsteuerung/System können Sie den Einschluss der Freebasic-Pfade in den aktuellen Pfad auch permanent machen. In Win2000/WinXP geschieht dies über "Erweitert"/"Umgebungsvariablen" und Änderung der Systemvariablen "Path". Die Aktualisierung wird allerdings erst beim nächsten Systemstart wirksam. Ich selbst bevorzuge diese Variante nicht, da man sich ev. mit der Zeit mehrere Freebasic-Verzeichnisse (neuere Versionen) zulegt und sich auf diese Art und Weise den permanenten aktuellen Pfad ziemlich "zumüllt".

Und was debuggen wir?

Am Besten ist für eine Schilderung des gdb ein Beispielprogramm, das wir debuggen. Ein solchen finden Sie hier. Es handelt sich um ein sehr einfaches Blockgrafik-Malprogramm. Mit den Cursortasten bewegt man den Cursor, mit der Leertaste schaltet man den Pinsel ein und aus und mit der PageUp-Taste ("Bild nach oben"-Taste) verändert man die Farbe des Pinsels. Probieren Sie es einmal aus. Was stellen Sie fest? Es funktioniert nicht! Es hat einen Fehler. Und es soll ja auch einen haben, wenn es zur Illustration eines Debuggers dienen soll...

Wie finden wir den Fehler? Zunächst müssen Sie sich dazu erstmal in den Quelltext etwas einlesen. Aber wenn Sie nicht über allen Massen gewitzt sind, werden Sie den Fehler nicht gleich auf den ersten Blick erkennen. Es hat etwas damit zu tun, dass das Cursorzeichen an der alten Position nicht entfernt wird. Aber dieses Entfernen ist in der Routine plotcursor() durchaus vorgesehen.

Das Blöde an der Debug-Situation ist, dass das, was wir in anderen Fällen als Debugging-Mittel nutzen mögen, hier schlecht funktioniert. Zwischenergebnisse auf den Bildschirm printen? Dann zerstören wir den Bildschirm, der ja gerade der Funktionskontrolle dienen muss. Loggen der Zwischenergebnisse in ein File? Schön - dann haben wir hinterher eine Liste mit Werten, aber wir wissen nicht, zu welchem Bildschirmergebnis sie jeweils gehören.

Start des Debugging-Vorgangs

Legen wir also mit dem gdb los. Dazu müssen wir ersteinmal auf der Konsole das Programm mit der Option "-g" kompilieren:

fbc -g test1.bas

Dann starten wir den gdb mit dem Namen des resultierenden exe:

gdb test1.exe

GNU gdb 5.2.1
Copyright 2002 Free Software Foundation, Inc.
GDB IS free software, covered by the GNU General PUBLIC License, AND you are
welcome TO change it AND/OR distribute copies of it under certain conditions.
Type "show copying" TO see the conditions.
There IS absolutely no warranty FOR GDB.  Type "show warranty" FOR details.
THIS GDB was configured AS "i686-pc-mingw32"...
(gdb) _

Wir befinden uns jetzt auf der gdb-Kommandozeile. Hier können wir gdb-Kommandos eingeben. Welche gdb-Kommandos gibt es? Dazu gibt es im WWW wiederum viele und gute Informationen, die meisten allerdings auf Englisch, z.B. hier.

Wir werden hier versuchen, die wichtigsten Kommandos und ihre wichtigsten Optionen zusammenzutragen.

Wichtig: Mit den Pfeiltasten Oben/Unten können genauso wie in der Konsole alte Kommandos wieder hergeholt werden.

quit

Das Wichtigste zuerst: Mit "quit" oder kurz "q" kommen wir wieder raus.

run

Geben wir auf der Kommandozeile "run" oder einfach ein "r" ein. Ein zweites Fenster öffnet sich, in dem das Programm ganz normal läuft. Das hilft uns also alleine nicht weiter.

Breakpoints

Eine wichtige Sache, die wir schon in QBASIC kennengelernt haben, sind "Breakpoints". In QBASIC ging das mit dem STOP-Befehl. In Freebasic funktioniert das nicht mehr: STOP ist gleichbedeutend mit END. Aber hier im gdb können wir in eine bestimmte Zeile einen virtuellen STOP-Befehl setzen, einen "Breakpoint". Setzen wir einen mal ganz an den Anfang des Programms:

(gdb) b
Breakpoint 4 at 0x78001000
(gdb) r
Starting program: N:\priv\comp\tutorial/kap341d.exe

Breakpoint 1, MAIN () at kap341d.bas:199
199       CLS

Wir haben einfach "b" eingetippt. Das setzt den Breakpoint auf den nächsten auszuführenden Befehl. Dann anschliessend ein "r" und das Programm hört sofort auf und zeigt die Zeile an.

Sie können hinter "b" nicht nur einen Zeilennummer, sondern auch einen Routinenamen angeben, ABER IN GROSSBUCHSTABEN!. Also z.B.

(gdb) b PLOTCURSOR
Breakpoint 6 at 0x401434: file kap341d.bas, line 95.

setzt ebenfalls einen Breakpoint in Zeile 95.

Das mit den Grossbuchstaben gilt für alle Symbole innerhalb des gdb (also auch Variablennamen, Konstantennamen usw.), da der fbc alle Symbolnamen dem gdb in Form von Grossbuchstaben übergibt!

Breakpoints listen

In der Regel werden wir Breakpoints allerdings an eine ganz bestimmte Stelle im Programm setzen, z.B. hier auf Beginn der plotcursor-Routine. Im Editor sehen wir, dass der erste Befehl (Achtung! DIM-Zeilen sind Deklarationen, keine Befehle), in Zeile 95 steht. Also geben wir ein:

(gdb) b 95
Breakpoint 5 at 0x401434: file kap341d.bas, line 95.

Wenn wir die Übersicht verloren haben, wo wir alles Breakpoints gesetzt haben, dann geben wir einen info-Befehl ein:

(gdb) info b
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x0040171b in MAIN at kap341d.bas:199
        breakpoint already hit 1 time
5   breakpoint     keep y   0x00401434 in PLOTCURSOR at kap341d.bas:95

"info b" ist die Kurzform für "info breakpoint" und wir sehen nun, wo wir alles Breakpoints gesetzt haben und sogar, wie oft sie schon das Programm passiert hat.

Breakpoints löschen

In unserem Beispiel wird plotcursor() laufend aufgerufen, auch wenn der Cursor gar nicht bewegt wurde und daher der Fehler noch gar nicht sichtbar wird. Es ist nicht besonders nützlich, wenn das Programm jedes Mal am Anfang von plotcursor() anhält (so ca. zweimal pro Sekunde), wenn der Cursor noch gar nicht bewegt wurde. Nun, in unserem Fall können wir das recht einfach dadurch beheben, dass wir den Breakpoint innerhalb des if (savebg=Isavebg)-Blocks setzen, weil dieser Block nur einmal nach einer Tastatureingabe betreten wird. (Siehe Aufbau der Routine blinkcursor()). Also löschen wir den alten Breakpoint erstmal. Das machen wir mit dem delete-Befehl, kurz "d", plus Nummer des Breakpoints, wie er durch info angezeigt wird:

(gdb) d 5
(gdb) info b
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x0040171b in MAIN at kap341d.bas:199
        breakpoint already hit 1 time

Hat funktioniert. Nun setzen wir ihn neu auf Zeile 97:

(gdb) b 97

Bedingte Breakpoints

Manchmal hat man aber keinen so praktischen IF-Block zur Verfügung. Nun, was man nicht hat, kann man sich natürlich schnell bauen. Man schreibt einfach drei Zeilen Dummy-Code in den Quelltext:

'Debug:
IF (testbedingung) THEN
  k=1'Dummyzeile, auf die der Breakpoint gesetzt werden kann.
END IF

Aber in einem laufenden Debuggingvorgang auszusteigen, den Code zu verändern und dann wieder einzusteigen, ist nicht nur umständlich, es hat auch den Verlust sämtlicher bisher gesetzter Breakpoints zur Folge. Viel praktischer ist es daher oft bedingte Breakpoints zu setzen, d.h. die Bedingung gleich direkt dem gdb mitzuteilen:

(gdb) b 97 IF CURSOR.Y==9
Breakpoint 8 at 0x40143c: file kap341d.bas, LINE 97.
(gdb) info b
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x0040171b in MAIN at kap341d.bas:199
        breakpoint already hit 1 TIME
8   breakpoint     keep y   0x0040143c in PLOTCURSOR at kap341d.bas:97
        STOP only IF CURSOR.Y == 9

...setzt z.B. einen Breakpoint, an dem nur gestoppt wird, wenn der Cursor Zeile 9 erreicht hat. Aber - was ist das mit dem doppelten Gleichheitszeichen??? Das ist doch ein Schreibfehler! Nein. Und warum dann so kompliziert? Warum ist das nicht einfach die Syntax von BASIC: IF (y=9( THEN ...???

Tja, der gdb ist ein universeller Debugger. Und wurde zuerst für die Programmiersprache C entwickelt. Ergo folgt die Syntax der if-Bedingungen (logischen Ausdrücke) der C-Syntax:

BASIC-SyntaxC-Syntax
= (Vergleich)==
<> (Vergleich)!=
AND&&
OR||
NOT!

Bisschen doof für BASIC-Programmierer, aber man gewöhnt sich dran...

Tracen

Stepping over

Nun wollen wir aber schrittweise mal loslegen. Um das Tracen richtig zu verstehen, wäre es wichtig, alle unbedingten Breakpoints innerhalb von plotcursor() zu löschen. "r" haben wir ja schon eingegeben und das Programm hat gleich bei "CLS" in main() angehalten. Die Eingabe des Befehls "next", kurz "n", veranlasst den gdb, die nächste Zeile zu verarbeiten.

Starting program: N:\priv\comp\tutorial/kap341d.exe

Breakpoint 1, MAIN () at kap341d.bas:199
199       CLS
(gdb) n
200       init
(gdb) n
203         s=cursorblink
(gdb) n
(hier bleibt der gdb "hängen">

"Next" verarbeitet immer die nächste Befehlszeile als Ganze, geht also in die SUB's und FUNCTION's nicht rein. Da cursorblink() nicht verlassen wird, solange der User keine Taste gedrückt hat, gehen nach cursorblink() im gdb weitere next's erstmal ins Leere. Gehen Sie erstmal ins Programmfenster und drücken Sie eine Cursortaste (am Besten nach oben). Dann geht's weiter...

Stepping into

Das Gegentstück zu "next" ist "step", kurz "s". Mit diesem gehe ich in die jeweilige SUB/FUNCTION, also Routine rein.

Finishing

Mit der Eingabe von "finish", kurz "fin", kann ich den gdb veranlassen, vollends die ganze Routine bis zum Rücksprung abzuarbeiten.

Continue

Vielleicht haben Sie nun sich mit "n" und "s" und "fin" ein Weilchen vorangearbeitet. Aber an sich ist das im vorliegenden Fall unnötig solange wir nicht an der Breakpoint-Position und -Bedingung angekommen sind. Es würde also genügen, das Programm einfach weiterlaufen zu lassen. Das geht mit Eingabe von "continue", kurz "c". Nach einem "Steppen" (so nennt man das Durchgehen des Programms im Einzelschritt) läuft damit das Programm wieder normal bis zum nächsten Breakpoint, Ereignis oder Ende.

Die Ausgabe von Werten

Nun sind wir an unserem Breakpoint und unserer Breakbedingung angekommen:

Breakpoint 1, PLOTCURSOR (SAVEBG=1) at kap341d.bas:97
97          xnew=cursor.x:ynew=cursor.y
(gdb)

Listen

Nun müssen wir erstmal wieder einen Blick in den Editor werfen, um zu sehen, was in Zeile 97 eigentlich los war. Es geht aber auch einfacher, und zwar über den list-Befehl oder kurz "l":

(gdb) l 92 93 dim xnew as integer, ynew as integer 94 95 IF (savebg=Isavebg) THEN 96 'First unplot the cursor at the old position 97 xnew=cursor.x:ynew=cursor.y 98 cursor.x=cursor.xold:cursor.y=cursor.yold 99 unplotcursor 100 'Then save the backround at the new position 101 cursor.x=xnew:cursor.y=ynew (gdb)

Wir sehen, dass gdb nun die aktuelle Ausführungsposition in die Mitte nimmt und drumherum ca. 5 Zeilen zeigt. Wenn das nicht ausreicht, kann man nochmal ein "l" ausgeben und erhält dann die nächsten Zeilen. Wenn die 10 Zeilen generell nicht ausreichen, kann man mit "set listsize 20" die Ausgabe vergrössern.

Ausgabe von Werten

Jetzt steppen wir einmal bis "unplotcursor". Das ist nun die eigentlich interessante Stelle. Schauen wir kurz im Editor nach: unplotcursor() benutzt die aktuellen Cursorkoordinaten cursor.x und cursor.y. Welche sind die nun? Wir geben nun einfach ein: "p CURSOR". Und erhalten:

(gdb) p CURSOR
$1 = {X = 40, Y = 12, XOLD = 40, YOLD = 12, COLHID = 7, SYMBHID = 32,
  COLHID2 = 0, SYMBHID2 = 0, COL = 10, SYMB = 75}
(gdb)

Wow! Das ist nun sehr viel besser als im QBASIC-Debugger! Wir bekommen gleich die ganze Struktur ausgespuckt! Und sehen auch gleich die Bescherung: Y steht auf 12. Aber wie wir durch unsere Breakpoint-Bedingung wissen, ist die aktuelle Cursorposition bei 9. Da wir von unten kommen, müsste die alte Cursorposition cursor.yold bei 10 stehen. Sie steht aber bei 12. Auf den Ausgangskoordinaten. Ein Blick ins Listing: Wo wird cursor.xold/yold eigentlich gesetzt? Nirgends! Das ist das Problem!

Hier gleich noch ein Tipp am Rande: Wir gehen wir (einigermassen) sicher, dass yold nirgends gesetzt wird? Nun, das setzen müsste mit einer Anweisung der Form ".yold=..." passieren. Also gehen wir ganz an den Anfang des Programms und suchen nach dem String ".yold=". Und wenn er nicht gefunden wurde, gibt's diese Anweisung eben auch nicht. Üben Sie, Ihre Augen zu entlasten, indem Sie "Suchen" (Search) intensiv einsetzen!

Reparatur

Und wo setzen wir yold und xold nun? Gemein wie ich immer bin, überlasse ich dies Ihnen als Übung...

Zusammenfassung: gdb-Kommandos

Im folgenden sind nicht nur nochmal alle Kommandos in einer Übersicht aufgelistet, ich habe auch gleich noch ein paar zusätzliche Kommandos unten angefügt.
qgdb verlassen
rProgramm laufen lassen
b MAINSorgt dafür, dass das Programm gleich bei der ersten Zeile anhält, damit man mit "n" oder "s" weitersteppen kann.
r <arg>Programm mit Kommandozeilenargumenten laufen lassen
b <n>Breakpoint an Zeile <n> setzen
b <fname>Breakpoint auf Eingang der Funktion <fname> setzen. Achtung! Bei FBC GROSSBUCHSTABEN!
b <n> if <Bdg.>Bedingten Breakpoint setzen. Bdg. z.B. "a==b" oder "a || b" oder "a && b" oder "a!=b" oder "!a && b" usw.
cPorgrammausführung fortsetzen
p <ausdr>Wert von des Ausdrucks <ausdr> anzeigen. Meist wird <ausdr> eine Variable sein. Kann aber auch ein Rechenausdruck sein, z.B. a+b. Wenn Sie also mal einen Taschenrechner brauchen...
nNächste Zeile als Einzelschritt ausführen. SUB's, Functions dabei nicht betreten.
sNächste Zeile als Einzelschritt ausführen, in SUB's, Functions eintreten.
finAusführung fortsetzen bis zum Rücksprung
lProgramm die nächsten Zeilen listen
set listsize <n>Anzahl Zeilen, die gelistet werden, verändern.
display <var>Zeigt Wert der Variablen laufend an.
del disp <n>Löschen der Variablenbeobachtung <n>
btBacktrace: Wenn in einem komplexen Programm ein Fehler auftritt, hat man oft keine Ahnung, wo dies geschah. Führt man das Programm im gdb aus und der Fehler tritt ein, dann kann man sich mit bt den s.g. "Stack" anzeigen lassen, in dem notiert ist, durch welche Routinen das Programm zuletzt gelaufen ist und mit welchen Argumenten diese Routinen jeweils aufgerufen wurden.
set <ausdr>Einer Variablen einen neuen Wert zuweisen. Ist ideal, um die Robustheit einer Routine innerhalb des gdb zu prüfen. "set CURSOR.Y=15" speichert 15 als neuen Wert in CURSOR.Y.