


EDB - Handbuch |
- Installation
- Schnelleinstieg
- Überblick
- EDB Kommandos
- Steuerung des Programmablaufs
- Quelltextfunktionen
- Datenfunktionen
- Symboltabellen-Kommandos
- Änderung des Programmablaufs
- Dateifunktionen
- Erweiterte Funktionen
- Remote Debugging
- Anpassung
- Hardwareschnittstellen
- Bei Problemen
Autor: Stefan Vollmar
Copyright © MCT Paul & Scherer Mikrocomputertechnik GmbH. Alle Rechte vorbehalten.
Dieses Handbuch, wie auch das beschriebene Produkt, wurde sorgfältig erstellt und geprüft. Trotzdem können Fehler und Irrtümer nicht ausgeschlossen werden. MCT übernimmt keinerlei Verantwortung für die uneingeschränkte Richtigkeit und Anwendbarkeit des Handbuchs oder des beschriebenen Produkts und für die aus eventuell vorhandenen Fehlern resultierenden Schäden.
Änderungen ohne vorherige Ankündigung vorbehalten.
![]()
1 Installation
1.1 Systemvoraussetzungen
PC mit CPU ab 386.
Mindestens 640KB Arbeitsspeicher. Ein kleiner Speicher führt zu langen Reaktionszeiten, da Daten immer wieder auf die Platte ausgelagert werden müssen. Dies macht sich insbesondere beim Debuggen von grossen Programmen bemerkbar. Empfehlenswert ist ein freier Arbeitsspeicher von mindestens 2MB.
Mindestens 2MB freier Plattenspeicher. Zusätzlich ist Plattenplatz für Auslagerungsdateien vorzusehen, der Bedarf richtet sich nach der Grösse der zu debuggenden Programme.
MS-DOS Betriebssystem ab Version 3.3.
ECO-C ab Version 2.07.
![]()
1.2 Registrierung
EDB wird ständig verbessert und weiterentwickelt. Damit Sie innerhalb des Update-Services an Neuentwicklungen teilhaben können, ist es erforderlich den beiliegenden Registrierungsbogen an MCT zu schicken.
![]()
1.3 Notationen
Da der Compiler und die gesamte Entwicklungsumgebung ursprünglich für Unix geschrieben wurde, werden alle Pfadnamen mit '/' - nicht mit Backslash - getrennt. Alle Backslashes in Environmentvariablen und der Kommandozeile des Compilers werden als erstes in '/' gewandelt. Daher werden alle Pfade mit '/' ausgegeben. In diesem Handbuch wird ebenfalls '/' als Pfadtrenner verwendet, falls dies möglich ist.
Hexadezimalzahlen werden wie in der Programmiersprache C mit '0x' eingeleitet, Oktalzahlen mit '0'.
![]()
1.4 Installation Schritt für Schritt
Legen Sie die mitgelieferte CD in Ihr CD-ROM-Laufwerk ein.
An der MS-DOS-Eingabeaufforderung wechseln Sie zum Verzeichnis edb auf der CD. Dann geben Sie install ein. Wenn Ihr CD-ROM-Laufwerk z.B. D: ist, geben Sie also folgendes ein:
d: cd edb installAlle weiteren Angaben werden vom Installationsprogramm interaktiv erfragt. Zunächst werden Sie nach dem Pfad gefragt, in dem EDB installiert werden soll. Hierbei ist es wichtig, den absoluten Pfadnamen einschliesslich Laufwerk anzugeben, z.B.:
c:\ecoEs ist sinnvoll, EDB im gleichen Verzeichnis wie ECO-C zu installieren. Die Installation ist damit abgeschlossen. Sie können jetzt die Beispiele in samples/edb ausprobieren. Die genaue Vorgehensweise wird im nächsten Kapitel erklärt.
![]()
1.5 Aktuelle Version
In der Datei doc/news-edb.txt finden Sie eine Zusammenfassung der Änderungen und Erweiterungen bis zur aktuellen Version. Die höchste, zuerst genannte Versionsnummer bezeichnet die aktuelle Version. In diesem Handbuch wird eventuell nicht die aktuellste Version beschrieben, in diesem Fall gelten die Angaben in der Datei.
![]()
1.6 Copyright
Für die Programme finden die Copyrightbestimmungen der FSF Anwendung, sie finden diese in der Datei doc/copying. Entsprechend den Copyrightbestimmungen der FSF (copyleft) sind die Quelltexte der Programme auf Anfrage gegen eine Unkostenpauschale erhältlich.
Die Bibliotheken und Beispiele können ohne urheberrechtliche Beschränkungen (Objektcode und Quelltexte) frei benutzt werden. Das Copyright liegt beim jeweiligen Copyrightinhaber.
![]()
2 Schnelleinstieg
Um das Beispiel in diesem Kapitel nachvollziehen zu können ist es erforderlich, dass Sie entweder ein Targetsystem mit serieller Verbindung und NICO-Monitor (mindestens Version 1.19) oder ein System mit Background-Debugging-Schnittstelle und PCfant-Adapter besitzen. Wenn Sie die Background-Debugging-Schnittstelle verwenden, muss ein Programm im ROM laufen, welches die Initialisierung des RAMs erledigt (z.B. NICO oder ROM C-Start).
![]()
2.1 Hardwareaufbau
Background-Debugger
Die Background-Debugger-Schnittstelle wird über den PCfant-Adapter mit einem PC-Druckerport (LPT1... 3) verbunden. Achten Sie bei der Verbindung zwischen PCfant und Target auf richtige Polung. Der Anschluss Nummer Eins ist sowohl am 16pol. Stecker als auch am Targetsystem mit einem Keil versehen. Bei Targetsystemen ohne JTAG-Port (Mega332 und Zwerg332) befindet sich lediglich ein 10pol. Debugging-Stecker auf der Platine, der mit den ersten 10 Anschlüssen der Buchse zusammengesteckt wird.
Wenn Sie nicht LPT1 als Port verwenden, sollten Sie jetzt die Environmentvariable EDBPORT setzen, sinnvollerweise geschieht dies in autoexec.bat.
Seriell
Als serielle Schnittstelle können Sie COM1 oder COM2 verwenden. Der serielle Treiber wird mit der bei der Installation generierten Batchdatei edbini.bat geladen. Der Treiber wird automatisch von EDB erkannt, daher entfällt die Angabe des seriellen Ports. Nachdem das Targetsystem mit dem PC verbunden ist, können Sie die Stromversorgung des Targets einschalten.
![]()
2.2 Beispielsession
Wechseln Sie in das Unterverzeichnis samples/edb und starten Sie die Beispielsession mit make bdm oder make serial, je nach verwendeter Schnittstelle. Falls ein anderes als das Standardtarget oder die Standardschnittstelle (COM1/LPT1) verwendet wird, ändern Sie das makefile entsprechend. Daraufhin wird das Programm first.c übersetzt und auf das Zielsystem geladen.
Jetzt können Sie verschiedene Kommandos benutzen, hier ein Überblick über die wichtigsten:
- Bei der BDM-Variante setzen Sie jetzt mit dem Kommando b main einen Breakpoint auf die Funktion main, danach starten Sie mit run.
- Die serielle Variante setzt automatisch den Breakpoint auf __main und startet das Programm anschliessend selbsttätig.
- b function/linenumber
- Setzt einen Breakpoint an den Anfang der Funktion function, oder auf die Zeile linenumber.
- c
- Setzt die Ausführung fort, bis ein Breakpoint auftritt, das Programm terminiert oder der Benutzer mit der Escape-Taste unterbricht.
- l
- Zeigt die Zeilen um die aktuelle Programmzeile, die Zeilen um den Anfang von function, oder die Zeilen um linenumber.
- n
- Die aktuelle Programmzeile wird ausgeführt. Wenn hier in eine Unterfunktion verzweigt wird, so wird diese ausgeführt und das Programm stoppt erst, wenn aus dieser Funktion zurückgekehrt wird.
- p variable
- Zeigt den Wert der Variablen variable an.
- q
- Auf dem Targetsystem wird ein Reset ausgelöst, danach wird der Debugger verlassen.
- s
- Die aktuelle Programmzeile wird ausgeführt, falls ein Funktionsaufruf erfolgt, stoppt das Programm am Beginn dieser Funktion.
![]()
2.3 Weitere Beispiele
Um die anderen Beispielprogramme im Verzeichnis samples/edb auszuprobieren, geben Sie folgende Komandozeile ein, wobei der Dateiname ohne die Extension angegeben wird:
make serial f=filename
Wenn Sie mit dem Background-Debugger arbeiten:
make bdm f=filename
![]()
3 Überblick
Mit EDB haben Sie verschiedene Möglichkeiten, ein Programm auf einem Targetsystem zu debuggen:
- Verwendung des in den Prozessor eingebauten Background-Debuggers. Dies hat den Vorteil, keine Kommunikationssoftware auf der Targetseite zu benötigen und schneller als die Verwendung der seriellen Schnittstelle zu sein, funktioniert aber nur bei Prozessoren mit diesem Feature, also alle Prozessoren mit CPU32(+) Kern. Dies erfordert einen zusätzlichen Adapter zum Anschluss des Background-Debugger-Ports an den Druckerport des Hostsystems (PC).
- Verwendung der sowieso vorhandenen seriellen Schnittstelle zur Targetkommunikation
- Unter Verwendung von NICO zur Initialisierung und zum Laden des Programms ins RAM, EDB übernimmt die Steuerung von NICO.
- Ein anderes Monitorprogramm lädt und startet das zu debuggende Programm. EDB wird danach gestartet.
- Generierung eines autonom im ROM ablauffähigen Programms. Das Programm kann mit einem EPROM-Simulator geladen werden bevor EDB gestartet wird.
![]()
3.1 Generierung der Programme
Die Programme müssen mit der -g Option übersetzt werden, damit die Debugginginformation (wie z.B. Zeileninformation) in die Symboltabelle der Objektmodule eingefügt wird. Beim Linken darf die Symboltabelle nicht mit der Option -s entfernt werden.
Soll der Debugger mit dem Targetsystem über die serielle Schnittstelle kommunizieren, muss die Bibliothek mit dem Kommunikationsmodul mit der Option -lsd dazugelinkt werden.
Soll das Programm nicht mit dem Monitorprogramm NICO geladen werden, sondern autonom aus dem ROM heraus ablauffähig sein, muss beim Linken die Option -Trdb zusätzlich zu -rom und -lsd angegeben werden. Mit dem Linkerscript rdb.ld wird das Programm mit einem Resetvektor versorgt und auf RAM-Adressen reloziert. Der ROM C-Start erkennt dies und kopiert auch das Textsegment ins RAM, dies ist nötig damit Breakpoints im Programm gesetzt werden können, ansonsten verhält sich diese Variante genau wie das ROM-fähige Programm.
![]()
3.2 Kommandozeilenoptionen
Der allgemeine Aufruf von EDB ist:
edb [options] [executable-file]
executable-file ist das ausführbare Programm mit Header und Symboltabelle inklusive Debugging-Information, dies kann auch mit file innerhalb des Debuggers angegeben werden.
Die Optionen im einzelnen:
- -?/-help
- Kurze Erklärung der Kommandozeilenoptionen.
- -q/-quiet
- Unterdrückt die Copyrightmeldung beim Programmstart.
- -batch
- EDB terminiert nachdem die Kommandozeile ausgeführt wurde.
- -nx
- Die Initialisierungsdatei edb.ini wird nicht ausgeführt. Normalerweise sucht EDB bei der Initialisierung im aktuellen Verzeichnis nach dieser Datei und führt sie als Kommandodatei aus.
- -cd dir
- Wechselt das Arbeitsverzeichnis nach dir.
- -directory dir
- Sucht Quelltexte auch im Verzeichnis dir.
- -x/-command commandfile
- Führt die Kommandodatei commandfile aus. Eine Kommandodatei ist eine Textdatei, bei der jede Zeile einer Kommandozeile bei interaktiver Eingabe entspricht.
- -b baudrate
- Die serielle Schnittstelle wird mit der Baudrate baudrate betrieben. Falls keine Baudrate angegeben ist erfolgt der Betrieb mit 19200Baud.
- -B
- Die Kommunikation mit dem Targetsystem erfolgt über den Background-Debugger.
- -D device
- Verwendet die Schnittstelle device zur Targetkommunikation (lpt1... 3 für den Background-Debugger, com1/2 für die serielle Schnittstelle).
- -L
- Lädt das ausführbare Programm ins Targetsystem (nicht möglich bei seriellem Debugging ohne NICO).
- -F file
- Es kann im BDM-Mode ein Programm ins FLASH des Targetsystems programmiert werden. Diese Option benötigt die Angabe des Targetrechners, da einige hardwareabhängige Einstellungen auf dem Targetsystem vorgenommen werden müssen.
- -T address
- Gibt die Downloadadresse (0x... ) für Programme an, die mit der Option '-F' ins FLASH programmiert werden sollen. Wird diese Option nicht angegeben, so wird das Programm an die Startadresse des FLASH gelegt.
- -target name
- Diese Option wird nur mit dem Schalter zusammen verwendet. Es werden Hardwareeinstellungen für das jeweilige mit name angegebene Target vorgenommen. Für name kann ZWERG332, MEGA332, SC332 oder MEGA340 eingesetzt werden.
- -S
- Die Kommunikation mit dem Targetsystem erfolgt über die serielle Schnittstelle.
- -no_auto
- Sämtliche automatischen Initialisierungen, die der EDB vornimmt, werden abgeschaltet. Diese Schalter ist nur sinnvoll wenn man ein eigenes Target verwendet, bei dem kein ablauffähiger C-Start im ROM vorliegt, da der EDB im Normalfall davon ausgeht dass die Initialisierung der Hardware durch einen C-Start im ROM vorgenommen wird. Wird -no_auto eingeschaltet, so wird angenommen, dass das zu debuggende Programm ab der Adresse 0 lauffähig ist.
![]()
3.3 Programmstart
Achtung: Bei seriellem Debugging führt die Eingabe von run während der Debugsession dazu, dass die Kommunikationsverbindung zum Targetrechner verlorengeht.
- r/run
- Das Programm wird unter der Kontrolle von EDB gestartet. Bevor das Programm gestartet wird, muss es gelesen (file-Kommando oder Kommandozeile) und zum Target übertragen werden (load-Kommando oder '-L' Switch). Bei Verwendung des seriellen Interface wird nach der Übertragung das Programm automatisch gestartet.
Da EDB über die serielle Schnittstelle nicht direkt mit der Targethardware "reden" kann, findet die Kommunikation auf dem Umweg über das zu debuggende Programm statt. Wenn man diesem nun sagt, es solle sich neu starten, dann versucht es das selbstverständlich: Zuerst terminiert es - und danach kann es natürlich keinerlei Aktionen mehr ausführen, geschweige denn sich selber wieder starten.
Hier hilft nur noch ein Reset des Targetrechners und Neustart des EDB. Dieser Effekt hat seine Ursache in den Mechanismen des seriellen Debugging und tritt bei Verwendung der Hardwaredebugschnittstelle deshalb nicht auf, da EDB in diesem Fall immer direkt mit dem Prozessor selbst "redet".
![]()
3.4 Programm beenden
- kill
- Das Programm wird beendet.
- quit
- Das Programm wird beendet und der Debugger verlassen.
![]()
4 EDB Kommandos
Die Befehle des EDB können auf die ersten paar Zeichen abgekürzt werden, wenn diese den Befehl unzweideutig identifizieren. Die meisten dieser Befehle können durch einfache Eingabe von RETURN in einer leeren Zeile wiederholt werden.
![]()
4.1 Befehlssyntax
EDB-Befehle bestehen aus einer einzelnen Eingabezeile. Für diese Zeile gibt es keine Längenbeschränkung. Sie beginnt mit einem Befehlsname, gefolgt von den dazugehörigen Argumenten. Der step-Befehl akzeptiert beispielsweise ein Argument, das angibt, wie viele Einzelschritte ausgeführt werden sollen, zum Beispiel step 5. Der step-Befehl kann auch ohne Argumente aufgerufen werden und führt dann einen einzelnen Schritt aus.
Einige Befehle werden immer ohne Argument aufgerufen.
Die Befehlsnamen des EDB können immer abgekürzt werden, wenn diese Abkürzung den Befehl eindeutig identifiziert. Andere mögliche Abkürzungen werden bei den Beschreibungen der einzelnen Befehle aufgeführt. In einigen Fällen sind auch zweideutige Abkürzungen erlaubt: 's' ist zum Beispiel gleichbedeutend mit step, auch wenn es noch andere Befehle gibt, die mit einem 's' beginnen.
Sie können Abkürzungen ausprobieren, indem Sie sie als Argumente für den -Befehl verwenden.
Eine leere Eingabezeile (ein einzelnes RETURN) bewirkt eine Wiederholung des letzten Befehls. Bestimmte Befehle, zum Beispiel run, können auf diese Weise nicht wiederholt werden. Dies sind Befehle, die bei unbeabsichtigter Wiederholung Probleme verursachen könnten oder die normalerweise nie wiederholt werden.
Die Befehle list und 'x' konstruieren bei der Wiederholung durch ein RETURN neue Argumente, statt die eingetippten nochmals zu verwenden. Dadurch kann man sich ohne viel Aufwand Quelltexte und Speicherbereiche auflisten lassen.
EDB verwendet RETURN noch zu einem anderen Zweck, nämlich um lange Ausgaben seitenweise auszugeben, ähnlich dem verbreiteten Hilfsprogramm "more". Da es in solchen Situationen passieren kann, dass RETURN unabsichtlich zu oft gedrückt wird, schaltet EDB die Befehlswiederholung bei Befehlen aus, die derartig lange Ausgaben erzeugen.
Jeder Text nach einem '#' bis zum Ende der Zeile ist ein Kommentar und wird nicht ausgewertet, dies ist vor allen in Befehlsdateien von Nutzen.
![]()
5 Steuerung des Programmablaufs
Die prinzipielle Aufgaben eines Debuggers sind: Ein Programm zu stoppen bevor es terminiert oder auftretende Probleme zu untersuchen und zu beheben.
Unter der Kontrolle des Debuggers kann ein Programm aus verschiedenen Gründen unterbrochen werden:
- Eine Prozessorexception.
- Ein Breakpoint.
- Eine neue Programmzeile wird nach einem step-Kommando ausgeführt.
Der Benutzer unterbricht das Programm mit Escape-Taste. Bei serieller Debuggerschnittstelle ist dies nur bei freigegebenen Interrupts möglich.
Ist ein Programm unterbrochen, können Variablen angezeigt und geändert werden, neue Breakpoints gesetzt oder alte gelöscht werden, um danach mit der Programmausführung fortzufahren. Normalerweise sorgen die Meldungen des EDB für eine ausreichende Erklärung über den Zustand des Programms - darüberhinaus kann diese Information zu jeder Zeit abgefragt werden.
- info programm
- Zeigt den Status des Programms: Ob es gestartet wurde oder nicht, welche Kommunikationsschnittstelle verwendet wird und warum es unterbrochen wurde.
![]()
5.1 Breakpoints, Watchpoints und Exceptions
Ein Breakpoint unterbricht ein Programm jedesmal wenn ein bestimmter Punkt im Programmcode erreicht wird. Zu jedem Breakpoint können verschiedene Bedingungen angegeben werden, die darüber entscheiden ob das Programm unterbrochen werden soll. Ein Breakpoint kann mit dem break-Kommando und dessen Varianten gesetzt werden. Die Position des Breakpoints kann durch eine Zeilennummer, einen Funktionsnamen oder der direkten Angabe einer Adresse erfolgen. Breakpoints können auch innerhalb von Funktionen zur Exceptionbearbeitung gesetzt werden.
Ein Watchpoint ist ein besonderer Breakpoint der das Programm immer dann unterbricht, wenn der Wert eines Ausdrucks (z.B. Programmvariable) sich verändert. Ein Watchpoint wird mit einem speziellen Kommando gesetzt, aber abgesehen davon kann er behandelt werden wie ein Breakpoint.
Immer wenn das Programm unterbrochen wird, können Programmvariablen angezeigt werden (siehe Kapitel Automatische Ausgabe).
EDB weist jedem Breakpoint oder Watchpoint eine fortlaufende Nummer zu, wenn er gesetzt wird. In vielen Kommandos zur Kontrolle der vielfältigen Eigenschaften von Breakpoints wird auf diese Nummer Bezug genommen. Jeder Breakpoint kann blockiert werden und hat damit keine Auswirkung auf die Programmausführung mehr, bis er wieder zugelassen wird.
Breakpoints setzen
Breakpoints werden mit dem break-Kommando oder kurz 'b' gesetzt. Die Debuggervariable "$bpnum" speichert die Nummer des zuletzt gesetzten Breakpoints.
Ein Breakpoint kann auf verschiedene Weise gesetzt werden:
EDB ermöglich das Setzen von mehreren Breakpoints an einer Stelle, dies ist sinnvoll wenn mehrere bedingte Breakpoints an einer Stelle gesetzt werden sollen.
- b/break function
- Setzt einen Breakpoint an den Anfang einer Funktion.
- break -/+ offset
- Setzt einen Breakpoint offset Zeilen vor beziehungsweise hinter der Stelle an der die Ausführung unterbrochen wurde.
- break linenum
- Setzt einen Breakpoint auf die Zeile linenum in der aktuellen Quelldatei. Das Programm wird gestoppt bevor der Code auf dieser Zeile ausgeführt wird.
- break filename:linenum
- Setzt einen Breakpoint auf die Zeile linenum in der Quelldatei filename.
- break filename:function
- Setzt einen Breakpoint an den Anfang der Funktion function in der Quelldatei filename.
- break *address
- Setzt einen Breakpoint an der Programmadresse address. Dies kann für Programmteile, die keine Debuggerinformation oder keine Quelltextdateien besitzen, verwendet werden.
- break...if cond
- Setzt einen bedingten Breakpoint. Jedesmal wenn der Breakpoint erreicht wird berechnet EDB den Ausdruck cond. Falls dieser ungleich Null (also WAHR) ist, wird die Ausführung des Programms unterbrochen. '...' steht für die oben genannten Spezifizierungen oder bleibt leer. Für weitere Informationen über Breakpoint-Bedingungen siehe Bedingte Breakpoints.
- tbreak args
- Der Breakpoint wird nach dem ersten Stop gelöscht. 1 Die Argumente sind die gleichen wie beim break-Kommando.
- rbreak regex
- Setzt Breakpoints an den Anfang aller Funktionen, die dem regulären Ausdruck regex genügen.
- info break/breakpoints [n]
- Zeigt alle Breakpoints an. Wenn die Breakpointnummer 'n' angegeben ist, wird nur der entsprechende Breakpoint angezeigt.
Watchpoints setzen
Watchpoints können benutzt werden um die Programmausführung zu stoppen, wann immer ein Ausdruck (z.B. Programmvariable) sich ändert, ohne eine bestimmte Stelle vorzugeben an der dies geschehen soll.
Watchpoints sollten nur wohlüberlegt benutzt werden, da sie die Programmausführung bei Remote-Debugging um den Faktor 1000 verlangsamen.
- wa/watch expr
- Setzt einen Watchpoint für den Ausdruck
- info watchpoints
- Zeigt alle Watchpoints an.
Löschen von Breakpoints
Häufig ist es erforderlich, einen Breakpoint oder Watchpoint zu beseitigen, wenn er seine Aufgabe erfüllt hat und nicht länger benötigt wird.
Mit dem clear-Kommando können Breakpoints durch Positionsangabe gelöscht werden. Mit dem delete-Kommando können einzelne Breakpoints oder Watchpoints mittels ihrer Breakpointnummer gelöscht werden.
- clear
- Löscht alle Breakpoints auf der nächsten Instruktion.
- clear function
- Löscht alle Breakpoints am Anfang der Funktion function.
- clear [filename:]linenum
- Löscht alle Breakpoints bei der Zeilennummer linenum.
- d/delete [breakpoints] [bnums... ]
- Löscht alle durch die Nummern bnums spezifizierten Breakpoints oder Watchpoints. Falls keine Argumente gegeben werden, werden alle Breakpoints gelöscht.
Breakpoints blockieren
Manchmal ist es sinnvoller Breakpoints zu blockieren anstatt sie zu löschen. Dies macht den Breakpoint inaktiv, genauso als wäre er gelöscht, erlaubt aber, dass der Breakpoint später wieder freigegeben wird.
Breakpoints und Watchpoints werden mit disable blockiert und mit enable wieder freigegeben.
- dis/disable [breakpoints] [bnums... ]
- Blockiert die angegebenen Breakpoints - oder alle Breakpoints falls keine Argumente gegeben sind. Ein blockierter Breakpoint ist wirkungslos, aber alle Information wie Position, Bedingung und Schleifenzähler bleiben erhalten.
- enable [breakpoints] [bnums... ]
- Gibt die angegebenen Breakpoints frei.
- enable [breakpoints] once [bnums... ]
- Gibt die angegebenen Breakpoints einmal frei.
- enable [breakpoints] delete [bnums... ]
- Gibt die angegebenen Breakpoints einmal frei und löscht sie danach.
Bedingte Breakpoints
Ein normaler Breakpoint unterbricht Ihr Programm jedes Mal wenn es eine bestimmte Stelle erreicht hat. Sie können Breakpoints aber auch eine Bedingung (condition) zuordnen. Eine Bedingung ist einfach ein Boolescher Ausdruck (expression) in der verwendeten Programmiersprache (siehe Kapitel Ausdrücke). Ein bedingter Breakpoint berechnet den Wert des Ausdruckes jedes Mal, wenn das Programm auf ihn trifft. Wenn der Wert des Ausdruckes WAHR ergibt, hält das Programm an.
Bedingungen können auch für Watchpoints gesetzt werden, um den Watchpoint zum Beispiel nur dann zu aktivieren, wenn die überwachte Variable einen ganz bestimmtem Wert erreicht.
Breakpoint-Bedingungen können Seiteneffekte haben und sogar Funktionen Ihres Programms aufrufen. Die Auswirkungen solcher Bedingungen sind immer vorhersagbar, ausser es befindet sich ein weiterer aktiver Breakpoint auf der gleichen Adresse. In diesem Fall kann es passieren, dass EDB den anderen Breakpoint zuerst sieht und das Programm anhält, noch bevor die Bedingung des ersteren überprüft werden konnte.
Breakpoint-Bedingungen werden beim Setzen eines Breakpoints durch ein if in der Argumentliste des break-Befehls definiert (siehe Kapitel Breakpoints setzen). Sie können jederzeit mit dem condition-Befehl geändert werden. Der watch-Befehl kennt keine if-Anweisung, der Befehl condition ist hier die einzige Möglichkeit, Bedingungen an Watchpoints zu knüpfen.
Eine besondere Breakpointbedingung ist es, erst dann zu stoppen wenn das Programm den Breakpoint zum n-ten Mal erreicht hat. Um dieses äusserst praktische Feature zu ermöglichen besitzt jeder Breakpoint einen -Zähler. Normalerweise steht er auf Null und hat deshalb keine Auswirkung, aber wenn das Programm einen Breakpoint erreicht, dessen Zähler nicht Null sondern einen positiven ganzzahligen Wert enthält, dann hält es an dieser Stelle nicht an, sondern verringert den Zählerwert um Eins und läuft weiter. Das bedeutet, dass ein Breakpoint mit einem -Zählerwert von erst dann das Programm anhält, wenn dieses zum -ten Mal an ihm vorbeikommt.
- condition bnum expression
- Setzt expression als Break-Bedingung für Breakpoint oder Watchpoint Nummer bnum. Von nun an wird der Breakpoint das Programm nur noch anhalten, wenn die Auswertung von ein logisches WAHR (nonzero in C) ergibt. Bei der Verwendung von condition überprüft EDB expression sofort auf syntaktische Richtigkeit und ob die darin enthaltenen Symbole im Kontext des Breakpoints verfügbar sind. Bei der Ausführung von condition wird expression jedoch noch nicht ausgewertet. Siehe auch Kapitel Ausdrücke.
- condition bnum
- Entfernt die Bedingung von Breakpoint Nummer bnum. Er wird zu einem normalen unbedingten Breakpoint.
Bei Breakpoints mit einem positiven ignore-Zählerwert und einer Breakpoint-Bedingung wird die Bedingung nicht ausgewertet. Die Auswertung erfolgt erst dann wieder, wenn der Zähler auf Null verringert wurde.
- ignore bnum count
- Setzt den ignore-Zähler des Breakpoints Nummer bnum auf den Wert count. Die nächsten count Male, die der Breakpoint erreicht wird, wird der Programmablauf nicht angehalten, der EDB führt an dieser Stelle (abgesehen vom dekrementieren des Zählerwertes) keine Aktionen aus. Um an einem Breakpoint beim nächstem Mal, da er erreicht wird, anzuhalten, muss ein Zählerwert von Null eingestellt werden.
- c/continue/fg count
- Setzt den Progammablauf fort und stellt den Zählerwert des Breakpoints, an dem das Programm gestoppt wurde auf count - 1. Das Programm wird an diesem Breakpoint erst dann wieder anhalten, wenn es ihn Mal erreicht hat. Das Argument für diesen Befehl hat nur dann einen Sinn, wenn das Programm durch einen Breakpoint gestoppt wurde. Zu jedem anderen Zeitpunkt wird das Argument vom EDB ignoriert. Die Anweisung fg ist nur ein Synonym und bietet genau die gleiche Funktionalität wie die anderen Formen dieses Befehls.
Sie können die Funktionalität des ignore-Zählers auch durch Verwendung einer Bedingung wie zum Beispiel "$foo-- <= 0" mit einer Debuggervariablen, die jedes Mal verringert wird, erreichen. Siehe dazu auch Kapitel Debuggervariablen.
Anweisungslisten für Breakpoints
Sie können jedem Breakpoint oder Watchpoint eine Liste von Anweisungen zuordnen, die jedes Mal ausgeführt wird, wenn das Programm an dieser Stelle angehalten wird. Sie können zum Beispiel die Werte bestimmter Ausdrücke ausgeben oder andere Breakpoints aktivieren.
Die Wiederholung des letzten Befehls durch Eingabe von RETURN ist innerhalb von Anweisungslisten nicht möglich.
- commands [bnum]
... command-list...
end- Definiert eine Anweisungsliste für Breakpoint Nummer bnum. Die Anweisungen werden in die auf commands folgenden Zeilen geschrieben. Durch Eingabe einer Zeile die nur ein end enthält wird die Anweisungsliste abgeschlossen.
Um eine Anweisungsliste von einem Breakpoint zu entfernen, muss lediglich commands mit einem direkt darauf folgenden end eingegeben werden.
Ohne ein bnum-Argument bezieht sich commands auf den zuletzt gesetzten Breakpoint oder Watchpoint (nicht auf den zuletzt erreichten!).
In Anweisungslisten können auch Befehle verwendet werden, die das Programm weiterlaufen lassen, zum Beispiel step, continue und ähnliche. Alle auf eine derartige Anweisung folgenden Befehle der Liste werden ignoriert, da bei jedem Schritt des Programms ein Breakpoint erreicht werden könnte, der wiederum mit einer Anweisungsliste versehen sein kann. Dies könnte zu Unklarheiten führen, welche Liste nun eigentlich abgearbeitet werden soll.
Wenn der erste Befehl einer Anweisungsliste silent ist, wird die normalerweise bei einem Breakpoint erscheinende Statusmeldung nicht ausgegeben. Dies kann erwünscht sein, wenn an diesem Breakpoint nur eine bestimmte Nachricht ausgegeben werden soll und das Programm dann sofort weiterlaufen soll. Wenn kein Befehl der Anweisungsliste eine Ausgabe erzeugt werden sie keinen Hinweis darauf erhalten, dass das Programm an diesem Breakpoint angehalten wurde. Der Befehl silent ist nur am Anfang einer Anweisungsliste sinnvoll.
![]()
5.2 Programmablauf steuern
- c/continue
- Setzt die Programmausführung an der Adresse fort, an der das Programm als letztes stoppte; alle Breakpoints auf dieser Adresse werden übergangen.
- continue ignore-count
- Das optionale Argument ignore-count veranlasst EDB, den Breakpoint die nächsten ignore-count Male zu ignorieren (siehe Bedingte Breakpoints).
- s/step
- Das Programm wird fortgesetzt bis eine andere Quelltextzeile erreicht wird. Falls eine Funktion ohne Debuginformation übersetzt wurde, wird die Programmausführung fortgesetzt bis eine andere Funktion erreicht wird.
- step count
- Das step-Kommando wird count mal ausgeführt. Falls zwischenzeitlich ein Breakpoint oder eine Exception auftritt, stoppt die Programmausführung unmittelbar.
- n/next [count]
- Verhält sich ähnlich wie das step-Kommando, die Programmausführung stoppt aber nicht wenn eine andere Funktion aufgerufen wird. Mit dem optionalen Argument wird das Kommando count mal wiederholt.
- finish
- Die Programmausführung wird fortgesetzt bis die aktuelle Funktion zum Aufrufer zurückkehrt. Falls ein Rückgabewert existiert, wird dieser angezeigt.
- u/until
- Das Programm wird ausgeführt bis die nächste Quelltextzeile erreicht wird. Dieses Kommando ist nützlich um in Schleifen nicht öfter als einmal zu stoppen. Bei einem Sprung wird die Ausführung so lange fortgesetzt bis die Adresse grösser ist als beim letzten Stop.
until hält das Programm in jedem Fall an, wenn der aktuelle Stackframe verlassen wird.
Wenn until ohne Argument aufgerufen wird, arbeitet er das Programm Instruktion für Instruktion im Einzelschrittverfahren durch und ist deshalb wesentlich langsamer als ein mit einem Argument.
- u/until location
- Die Programmausführung wird fortgesetzt bis location erreicht wird, oder die aktuelle Funktion verlassen wird. Für location sind alle Positionsangaben, die für Breakpoints Verwendung finden, zulässig. Diese Form des Kommandos verwendet Breakpoints statt Einzelschrittbearbeitung und wird daher schneller abgearbeitet als die vorhergehende.
- si/stepi
- Eine Maschineninstruktion wird ausgeführt. Um bei jedem Stop die aktuelle Instruktion anzuzeigen kann "display/i $pc" eingegeben werden (siehe Kapitel Automatische Ausgabe). Wie beim step-Kommando kann ein Wiederholungszähler angegeben werden.
- ni/nexti
- Eine Maschineninstruktion wird ausgeführt. Wenn dabei eine Funktion aufgerufen wird so wird diese ausgeführt bevor das Programm stoppt.
![]()
5.3 Exceptions
Beim Programmstart werden alle Exceptionvektoren auf einen internen Handler des Debuggers gelenkt, damit ist gewährleistet, dass alle nicht vom Programm bedienten Exceptions abgefangen werden. Installiert das Programm Exceptionhandler, kann der Debugger diese Exception nicht mehr abfangen. Um einen Exceptionhandler zu debuggen, kann ein Breakpoint innerhalb des Handlers gesetzt werden. Mit dem Beispielprogramm samples/edb/except.c kann das Verhalten bei Exceptions ausprobiert werden. 2
Unterbricht der Anwender mit Escape das Programm, wird eine Exception mit der Nummer Null simuliert.
Bei manchen Exceptions (Buserror, Addresserror, Breakpoint Instruction) zeigt der Programmzähler nicht auf die nächste Instruktion, sondern auf die Instruktion welche die Exception verursacht hat. Mit dem jump-Kommando kann an einer anderen Stelle mit der Ausführung fortgefahren werden.
Buserror Exception
Der Prozessor-Kontext kann bei Buserror - und Addresserror Exceptions auf MC68000-Prozessoren, im Gegensatz zu CPU32 und MC68020, nicht wiederaufgesetzt werden. Der Debugger baut den Stack um, als wäre eine gewöhnliche Exception aufgetreten. Der Programmzähler zeigt dann möglicherweise auf die folgende Instruktion. Es bleibt auch unklar, ob eventuell ein Teil der Instruktion ausgeführt wurde (z.B. bei movem). Diese Einschränkung ist eine Eigenschaft des MC68000-Prozessors.
![]()
6 Quelltextfunktionen
EDB kann Teile des Quelltexts ausgeben, wenn das Programm die Debugging-Information enthält und dem Debugger das Quelltextverzeichnis bekannt ist. Wenn das Programm stoppt, zeigt EBD automatisch die Quelltextzeile in der das Programm stoppte.
![]()
6.1 Quelltextausgabe
Das list-Kommando dient zur Ausgabe des Quelltextes.
Folgende Liste enthält die möglichen Formen des Kommandos:
Standardmässig werden 10 Zeilen Quelltext ausgegeben, mit dem set listsize-Kommando kann dieser Wert geändert werden:
- l/list linenum
- Gibt Quelltext zentriert um die Zeile linenum in der aktuellen Quelltextdatei aus.
- list function
- Gibt Quelltext zentriert um den Anfang der Funktion function aus.
- list
- Es werden weitere Zeilen ausgegeben. Wenn die letzte Quelltextausgabe im Rahmen einer Programmunterbrechung erfolgte (Einzelschritt, Breakpoint, Exception, ... ), werden die Zeilen um die aktuelle Zeile herum angezeigt, ansonsten werden die auf die letzte Quelltextanzeige folgenden Zeilen angezeigt.
- list -
- Es werden die vorhergehenden Zeilen angezeigt.
Die Wiederholung eines list-Befehls durch ein RETURN ignoriert die Argumente und entspricht der Eingabe eines einfachen list. Dies ist sinnvoller als eine erneute Ausgabe der selben Zeilen. Eine Ausnahme bildet das Argument '-', bei der Wiederholung eines solchen Befehls werden auch weiterhin jeweils die vorhergehenden Zeilen aufgelistet.
- set listsize count
- Folgende Kommandos zeigen count Quelltextzeilen an.
- show listsize
- Zeigt die aktuelle Anzahl von dargestellten Zeilen an.
Der list-Befehl erwartet entweder null, ein, oder zwei Argumente. Argumente können in verschiedenen Formen auftreten, aber sie kennzeichnen immer bestimmte Quelltextzeilen (linespecs). Hier ist die vollständige Liste der möglichen Argumente für den list-Befehl :
Hier sind sämtliche Möglichkeiten, eine einzelne Quelltextzeile als Parameter zu beschreiben (linespecs):
- list linespec
- Zeigt die Zeilen um linespec herum an.
- list first,last
- Zeigt die Zeilen von first bis last an. Beide Argumente sind linespecs.
- list ,last
- Zeigt Zeilen bis last an.
- list first
- Zeigt Zeilen ab first an.
- list +
- Zeigt die Zeilen nach der zuletzt angezeigten an.
- list -
- Zeigt die Zeilen vor der zuletzt angezeigten an.
- list
- Beschreibung siehe oben.
- number
- Bezeichnet Zeile number der aktuellen Quelldatei. Wenn ein line-Befehl zwei linespecs hat, ist die gleiche Quelldatei wie beim ersten linespec gemeint.
- +offset
- Bezeichnet die Zeile, die offset Zeilen nach der zuletzt ausgegebenen Zeile liegt. Bei der Verwendung als zweites linespec eines list-Befehls bezeichnet es die Zeile, die offset Zeilen nach dem ersten linespec kommt.
- -offset
- Bezeichnet die Zeile, die offset Zeilen vor der zuletzt ausgegebenen Zeile liegt.
- filename:number
- Bezeichnet die Zeile number in der Quelldatei filename.
- function
- Bezeichnet die Zeile der geschweiften Klammer ('{'), mit der der Funktionskörper der Funktion function beginnt.
- filename:function
- Bezeichnet die Zeile der geschweiften Klammer ('{'), mit der der Funktionskörper der Funktion function in der Datei filename beginnt. Die Angabe eines Dateinamens zu einer Funktion ist nur zur Vermeidung von Mehrdeutigkeiten erforderlich, wenn gleiche Funktionsnamen in verschiedenen Quelldateien existieren.
- *address
- Bezeichnet die Zeile, die die Programmadresse address enthält. Für address können beliebige Ausdrücke verwendet werden.
![]()
6.2 Suche im Quelltext
- fo/search/forward-search regexp
- Durchsucht jede auf die zuletzt angezeigte Quelltextzeile folgende nach einer Übereinstimmung mit dem regulären Ausdruck regexp. Alle gefundenen Zeilen werden ausgegeben.
- rev/reverse-search regexp
- Durchsucht jede der zuletzt angezeigten Quelltextzeile vorangehende Zeile nach einer Übereinstimmung mit dem regulären Ausdruck regexp. Alle gefundenen Zeilen werden ausgegeben.
![]()
6.3 Quelltextverzeichnisse
Falls die Quelltexte nicht im gleichen Verzeichnis wie das ausführbare Programm und der Pfad nicht im Programm gespeichert ist, muss der Quelltextpfad mit dem directory-Kommando spezifiziert werden:
- directory dirname
- Fügt den Pfad dirname an den Beginn der Liste der Quelltextpfade an. Dieser Pfad wird dannn vor allen anderen nach den Quelltextdateien durchsucht.
- directory
- Löscht die Liste der Quelltextverzeichnisse.
- show directory
- Gibt die Liste der Quelltextverzeichnisse aus.
![]()
6.4 Quelltext und Maschinencode
Mit dem Kommando info line können die zu einer Quelltextzeile gehörenden Programmadressen und die zu einer Programmadresse gehörende Quelltextzeile angezeigt werden. Das Kommando disassemble erlaubt es, einen Adressbereich als Assemblercode auszugeben.
- info line linespec
- Gibt die Start- und Endadresse des übersetzten Programms für die Quelltextzeile linespec aus. Wird eine Programmadresse mit *addr als Zeilenspezifikation angegeben, wird die entsprechende Zeilennummer ausgegeben.
- disassemble startaddr endaddr
- Der Adressbereich von startaddr bis endaddr wird disassembliert ausgegeben.
![]()
7 Datenfunktionen
Allgemein lassen sich Daten mit dem print-Kommando (Kurzform 'p') oder dem Synonym inspect bearbeiten.
Auf Speicherebene können Daten mit dem x-Kommando bearbeitet werden. Siehe hierzu auch Kapitel Speicherbearbeitung.
- print [/f] exp
- Der Ausdruck exp wird berechnet und ausgegeben. Enthält der Ausdruck eine Zuweisung wird die entsprechende Variable vor der Ausgabe verändert. Ohne die Formatangabe /f erfolgt die Ausgabe in einem dem Datentyp von exp entsprechenden Format, andere Formate können durch geeignete Wahl des Parameters 'f' aktiviert werden (siehe auch Kapitel Ausgabeformate).
- print [/f]
- Ohne Angabe des Arguments zeigt EDB den letzten Wert noch einmal an. Dies erlaubt in Verbindung mit der Formatangabe /f die bequeme Untersuchung eines Ausdruckes in verschiedenen Ausgabeformaten.
Um den Datentyp eines Ausdrucks auszugeben verwenden Sie das ptype exp-Kommando (siehe Kapitel Symboltabellen-Kommandos).
![]()
7.1 Ausdrücke
print und viele andere EDB Kommandos akzeptieren einen Ausdruck und berechnet diesen. Jede Art von Konstanten, Variablen und Operatoren, die von der benutzten Programmiersprache definiert sind ist erlaubt, einschliesslich Zuweisungen, bedingte Ausdrücke, Funktionsaufrufe, Typenkonversion und Stringkonstanten. Symbole die mit dem Präprozessorkommando #define definiert wurden, können nicht benutzt werden.
Zusätzlich zu den Operatoren der Programmiersprache unterstützt EDB folgende Operatoren:
- @
- Ein binärer Operator um Teile des Speichers als Array zu behandeln. Siehe auch Kapitel Künstliche Arrays.
- ::
- Erlaubt die Spezifizierung einer Variable mit der Angabe der Quelltextdatei oder der Funktion. siehe auch Kapitel Programmvariablen.
- {type} addr
- Referenz auf ein Objekt vom Typ an der Speicherstelle addr. addr kann ein beliebiger Ausdruck sein dessen Wert ein Integer oder ein Zeiger ist. Diese Konstruktion ist unabhängig vom Typ der normalerweise an der Speicherstelle erwartet wird zulässig.
![]()
7.2 Programmvariablen
Die häufigste Art von Ausdrücken ist der Name einer Variablen im Programm.
Variablen in einem Ausdruck beziehen sich immer auf die aktuelle Position im Programm. Nur auf Variablen des aktuelle Gültigkeitsbereichs kann so Bezug genommmen werden.
Um auf eine Variable oder Funktion Bezug zu nehmen die nur in einer Datei gültig ist wird folgende Notation benutzt:
file::variable
Wenn auf eine bestimmte Variable in einer bestimmten Funktion Bezug genommen werden soll, kann folgende Notation benutzt werden:
function::variable
Die Bezeichnungen file und function beziehen sich hier auf den Kontext der benutzten Variablen. Bei der Angabe von Dateinamen können Anführungszeichen verwendet werden um sicherzustellen, dass EDB den Namen als einzelnes Wort auswertet - ein Punkt innerhalb eines Dateinamens wird normalerweise als Trennzeichen interpretiert, was an dieser Stelle normalerweise nicht gewünscht ist.
Um also eine globale Variable x anzuzeigen, die in der Datei f2.c definiert ist, kann folgende Anweisung verwendet werden:
(edb) print 'f2.c'::x
Eine Warnung: Gelegentlich scheinen lokale Variablen an bestimmten Stellen einer Funktion falsche Werte zu enthalten, nämlich direkt nach dem Eintreten in einen neuen Kontext und direkt vor dem Ende der Funktion. Dieses Problem tritt vor allem auf, wenn Sie schrittweise Maschinenbefehle abarbeiten. Dies liegt daran, dass bei den meisten Prozessorarchitekturen mehr als eine Maschineninstruktion zum Initialisieren des Stacks und der lokalen Variablen benötigt wird. Variablen scheinen dann falsche Werte zu enthalten, bis der Stack vollständig initialisiert ist. Auch das Löschen der lokalen Variablen und des Stacks benötigen meistens mehrere Instruktionen, so dass bei Verlassen der Funktion plötzlich Werte "verschwinden" können.
![]()
7.3 Künstliche Arrays
Häufig ist es nützlich mehrere aufeinanderfolgende Objekte des gleichen Typs auszugeben.
Mit dem binären Operator '@' kann ein künstliches Array erzeugt werden. Zur Linken des '@' steht das erste Element des Arrays, rechts die gewünschte Anzahl von Elementen. Angenommen, im Quelltext steht:
int *array = (int *)malloc(len * sizeof(int));
Der Inhalt von array kann dann mit folgender Sequenz ausgegeben werden:
p *array@len
![]()
7.4 Ausgabeformate
Normalerweise ist das Ausgabeformat vom Datentyp abhängig. Manchmal muss jedoch ein bestimmtes Ausgabeformat erzwungen werden. Dies erreicht man durch Anhängen eines '/'und eines darauf folgenden Formatbuchstabens. Folgende Formate werden unterstützt:
Das folgende Beispiel gibt den Programmzähler hexadezimal aus (siehe Kapitel Prozessorregister):
- x
- Integer in hexadezimaler Darstellung.
- d
- Integer in dezimaler Darstellung mit Vorzeichen.
- u
- Integer in dezimaler Darstellung ohne Vorzeichen.
- o
- Integer in oktaler Darstellung.
- t
- Integer in binärer Darstellung.
- a
- Ausgabe als Adresse, sowohl als hexadezimalen Absolutwert als auch als Offset zum nächsten davorliegenden Symbol. Dieses Format kann benutzt werden um herauszufinden, wo (in welcher Funktion) eine unbekannte Adresse liegt:
(edb) p/a 0x54320
$3 = 0x54320 <_initialize_vx+396>- c
- Integer als Zeichenkonstante.
- f
- Fliesskommazahl.
p/x $pc
Beachten Sie, dass vor dem '/' kein Leerzeichen benötigt wird, da in EDB-Befehlsnamen kein '/' vorkommen kann.
Um den zuletzt ausgegebenen Wert in einem anderen Format anzuzeigen können Sie einfach den print-Befehl mit einer Formatangabe, aber ohne Argument eingeben. Beispielsweise gibt "p/x" den zuletzt ausgegebenen Wert als Hexadezimalzahl aus.
![]()
7.5 Speicherbearbeitung
Zum Beispiel gibt "x/3uh 0x54320" drei Halbworte ('h') formatiert als vorzeichenlose Ganzzahl ('u') ab der Adresse 0x54320 aus.
- x/nfu
- Hiermit kann der Speicherinhalt unabhängig von den Programmdaten und dem Programmstatus dargestellt werden. Es kann eine Speichereinheit 'u', ein Wiederholungszähler 'n' und das Format 'f' spezifiziert werden. 'x' versteht ausser den Formaten 'f', die auch von print verwendet werden, die beiden Formate 's' (Zeichenkette, String) und 'i' (Maschinenbefehl, Instruktion).
Da die Buchstabenliste für die Formatierung sich nicht mit der Buchstabenliste für die Speichereinheiten überschneidet, ist die Reihenfolge der Parameter bedeutungslos.
Der Ausdruck wird als die Adresse interpretiert, ab der EDB den Speicher liest, unabhängig davon ob es sich um eine Adresse oder eine Ganzzahl handelt.
Liste der Speichereinheiten:
'x' kennt zwei zusätzliche Ausgabeformate:
- b
- Ein einzelnes Byte.
- h
- Ein Halbwort, zwei Bytes.
- w
- Ein Wort, vier Bytes.
- g
- Ein "gigantisches" Wort, acht Bytes.
- s
- Gibt eine nullterminierte Zeichenkette aus. Jegliche Speichereinheit wird ignoriert und so viele Zeichen ausgegeben bis ein Nullzeichen erreicht ist.
- i
- Gibt Maschineninstruktionen in Assemblersyntax aus, auch hier wird eine eventuelle Speichereinheit ignoriert. Alternativ kann das Kommando disassemble verwendet werden.
![]()
7.6 Automatische Ausgabe
Den Wert eines Ausdrucks kann mit dem display-Kommando bei jedem Programmstop automatisch ausgegeben werden. Bei der Ausgabe wird jeweils eine Nummer zur Identifizierung, der Ausdruck selbst und dessen Wert dargestellt. Der Befehl display wird durch ein RETURN nicht wiederholt.
- display exp
- Ausdruck wird an die Anzeigeliste angehängt.
- display/fmt exp fmt
- spezifiziert nur ein Ausgabeformat und keine Grössenangabe oder Zähler. Siehe auch Kapitel Ausgabeformate.
- display/fmt addr
- Für die Formate 'i' oder 's', oder falls ein Ausgabeformat oder eine Grössenangabe enthält, wird der Ausdruck addr als Speicheradresse interpretiert. Die Ausgabe entspricht "x/fmt addr".
- undisplay/delete display dnums...
- Löscht den Eintrag Nummer dnum aus der Anzeigeliste.
- disable display dnums...
- Blockiert den Eintrag Nummer dnum.
- enable display dnums...
- Gibt den Eintrag Nummer dnum wieder frei.
- display
- Zeigt die Werte der Anzeigeliste an.
- info display
- Zeigt die Liste der Ausdrücke mit ihrer jeweiligen Nummer, aber ohne die entsprechenden Werte an.
![]()
7.7 Ausgabevoreinstellungen
EDB stellt mehrere Möglichkeiten zur Verfügung, die Ausgabeformate von Arrays, Strukturen und Symbolen einzustellen.
- set print address [on]
- EDB zeigt bei der Ausgabe von Stackframes, Struktur- und Zeigerwerten, Breakpoints und ähnlichem die jeweiligen Speicheradressen an, auch wenn gleichzeitig der Inhalt dieser Adressen angezeigt wird. Die Voreinstellung ist . Die Anzeige eines Stackframes sieht bei Verwendung von "set print address on" etwa folgendermassen aus:
(edb) f
#0 setquote (lq=0x34c78 «<",rq=0x34c88 »>") at x.c:530
530 if (lquote != def_lquote)- set print address off
- Zeigt bei der Ausgabe von Werten nicht deren Adresse an. Das vorangegangene Stackframe-Beispiel würde bei der Einstellung "set print address off" folgendermassen aussehen:
(edb) set print address off
(edb) f
#0 setquote (lq=«<", rq=»>") at x.c:530
530 if (lquote != def_lquote)Sie können "set print address off" benutzen um alle maschinenabhängigen Ausgaben des EDB zu unterdrücken. Dadurch bekommen Sie immer den gleichen Text auf allen Maschinen, ob nun Zeigerargumente verwendet werden oder nicht.
- show print address
- Zeigt an ob Adressen ausgegeben werden oder nicht.
- set print array [on]
- EDB wird Arrays formatiert ausgeben. Diese formatierte Ausgabe ist besser lesbar, nimmt aber mehr Platz in Anspruch. Die Voreinstellung ist off.
- set print array off
- Schaltet die formatierte Ausgabe von Arrays aus.
- show print array
- Zeigt an, ob formatierte oder unformatierte Arrayausgabe eingestellt ist.
- set print elements number-of-elements
- Wenn EDB grosse Arrays ausgibt, hält er die Ausgabe nach der im Argument von "set print elements" angegebenen Zahl von Elementen an. Diese Begrenzung gilt auch für die Anzeige von Strings.
- show print elements
- Zeigt die Anzahl der Array-Elemente an, nach der EDB die Ausgabe anhält.
- set print pretty on
- Veranlasst EDB dazu, Strukturen in eingerücktem Format mit einem Element pro Zeile darzustellen.
Ein Beispiel:
$i = { next = 0x0, flags = { sweet = 1, sour = 1 }, meat = 0x54 "Pork" }- set print pretty off
- EDB stellt Strukturen in kompaktem Format dar.
Noch einmal das Beispiel:
$i = { next = 0x0, flags = { sweet = 1, \ sour = 1 }, meat = 0x54 "Pork" }- show print pretty
- Zeigt an, welches Format EDB für die Darstellung von Strukturen verwendet.
- set print sevenbit-strings on
- Weist EDB an, nur sieben-Bit-Zeichen darzustellen. Alle Zeichen mit acht Bit (in Strings oder Zeichenvariablen) werden in der numerischen Notation \nnn dargestellt.
- set print sevenbit-strings off
- Zeigt Zeichen mit sieben oder acht Bit an, je nach Bedarf. Dies ist die Voreinstellung.
- show print sevenbit-strings
- Zeigt an, ob EDB die Ausgabe auf sieben Bit begrenzt oder nicht.
- set print union on
- EDB zeigt Unions an, die in Strukturen enthalten sind. Dies ist die Voreinstellung.
- set print union off
- Unterdrückt die Ausgabe von Unions innerhalb von Strukturen.
- show print union
- Zeigt an, ob in Strukturen enthaltene Unions angezeigt werden oder nicht.
- set print max-symbolic-offset maxoff
- Veranlasst EDB dazu, nur die symbolische Form einer Adresse anzuzeigen, wenn der Offset zwischen dem nahesten vorherigen Symbol und der Adresse kleiner als maxoff ist. Die Voreinstellung für maxoff ist 0, das bedeutet dass EDB immer die symbolische Form einer Adresse ausgibt, wenn ihr ein Symbol voranging.
- show print max-symbolic-offset:Zeigt an, welcher Wert für maxoff eingestellt ist.
![]()
7.8 Wertehistory
Mit ausgegebene Werte werden in der Wertehistory (value history) des EDB gespeichert, so dass man sich in anderen Ausdrücken wieder darauf beziehen kann. Die Werte bleiben erhalten, bis die Symboltabelle neu eingelesen oder verworfen wird (zum Beispiel mit den Befehlen file oder symbol-file). Wenn sich die Symboltabelle ändert, wird die Wertehistory ebenfalls gelöscht, da die Historywerte Zeiger auf in der alten Symboltabelle definierte Typen enthalten könnten.
Ausgegebene Werte bekommen eine Nummer (history number) zugewiesen, um sie später referenzieren zu können. Diese Nummern sind fortlaufenden Ganzzahlen, der Anfangswert ist Eins. Der print-Befehl zeigt die Historynummer durch ein dem ausgegebenen Wert vorangestelltes "$num = " an, num ist hier die jeweilige Historynummer.
Um frühere Werte zu referenzieren wird ein '$', gefolgt von der Historynummer, verwendet. Ein alleinstehendes '$' bezieht sich auf den zuletzt ausgegebenen Wert, '$$' auf dessen Vorgänger. Ein '$$n' bezieht sich auf den n-ten Wert vor dem Ende der Liste, '$$2' ist also der Wert vor '$$', '$$1' ist gleichwertig mit '$$' und '$$0' entspricht '$'.
Wenn Sie also gerade den Zeiger auf eine Struktur mit print ausgegeben haben und nun den Inhalt der Struktur untersuchen wollen, so reicht ein einfaches "p *$" aus.
Falls Sie eine verkettete Liste von Strukturen haben, in der die Komponente next auf den Nachfolger zeigt, können Sie sich den Inhalt der nachfolgenden Struktur mit "p *$.next" ansehen. Durch einfaches Wiederholen dieser Anweisung - zum Beispiel durch Drücken von RETURN - können Sie nun Schritt für Schritt alle folgenden Elemente der Liste anzeigen lassen.
Beachten Sie, dass in der History Werte, keine Ausdrücke, gespeichert sind. Wenn der Wert von x Vier ist und Sie folgende Befehle eingeben:
print x
set x=5dann bleibt der von print in der Wertehistory gespeicherte Wert Vier, obwohl sich der Wert von x geändert hat.
- show values
- Gibt die letzten zehn Werte der History mit ihren Historynummern aus. Dies entspricht der zehnmaligen Eingabe von "p $$9", allerdings wird die History durch show values nicht verändert.
- show values n
- Zeigt zehn Historywerte an, zentriert um den Historyeintrag Nummer n.
- show values +
- Zeigt die zehn Historywerte an, die auf die letzte Historyausgabe folgen. Falls keine Folgeeinträge mehr vorhanden sind wird nichts angezeigt.
Die Eingabe von RETURN, um show values zu wiederholen, hat den gleichen Effekt wie show values +.
![]()
7.9 Debuggervariablen
EDB stellt spezielle Variablen (convenience variables) zur Verfügung, in denen Sie Werte speichern und später darauf Bezug nehmen können. Diese Variablen existieren nur innerhalb des EDB und sind nicht Teil des zu debuggenden Programms. Sie haben keinerlei Einfluss auf den Programmablauf und können deshalb nach Belieben verwendet werden.
Debuggervariablen sind durch ein vorangestelltes '$' gekennzeichnet. Jeder mit einem '$' beginnende Name kann für Debuggervariablen benutzt werden, ausser es handelt sich um einen der voreingestellten maschinenspezifischen Registernamen. Lesen Sie hierzu auch Kapitel Prozessorregister. Referenzen auf die Wertehistory (Kapitel Wertehistory) sind im Gegensatz dazu Nummern mit vorangestelltem '$'.
In diesen Variablen können durch einfache Zuweisung Werte gespeichert werden:
set $foo = *object_ptr
Diese Anweisung speichert den Inhalt der Adresse object_ptr in der Variablen foo.
Die erste Verwendung einer Debuggervariablen erzeugt diese, ihr Inhalt ist void bis ihr ein anderer Wert zugewiesen wird. Sie können den Inhalt durch Zuweisung zu jedem beliebigen Zeitpunkt ändern. Diese Variablen haben keinen festen Datentyp. Es können per Zuweisung beliebige Werte, einschliesslich Strukturen und Arrays zugewiesen werden, selbst wenn die Variable vorher einen anderen Datentyp enthalten hat. Wenn eine Variable in einem Ausdruck verwendet wird hat sie den Typ des in ihr enthaltenen Wertes.
Anwendungen für Debuggervariablen sind zum Beispiel Zähler, die inkrementiert werden oder Zeiger, die weitergerückt werden. Um beispielsweise ein Feld von aufeinanderfolgenden Elementen aus einem Array von Strukturen auszugeben kann man folgende Anweisungen benutzen:
- show convenience
- Zeigt eine Liste der bisher verwendeten Debuggervariablen und deren Inhalte. Kann mit show con abgekürzt werden.
set $i = 0
print bar[$i++]->contents... Wiederholen der Anweisung durch RETURN
Einige Debuggervariablen werden automatisch von EDB erzeugt und mit bestimmten Werten initialisiert:
- $_
- Die Variable $_ wird vom x-Befehl automatisch auf die letzte untersuchte Adresse gesetzt (siehe Kapitel Speicherbearbeitung). Andere Befehle, die eine Adresse für x voreinstellen setzen ebenfalls $_ auf diese Adresse. Zu diesen Befehlen gehören beispielsweise info line und info breakpoint. Der Datentyp von $_ ist void *, ausser wenn er vom x-Befehl gesetzt wird, in diesem Fall ist er ein Zeiger auf den Typ von $__.
- $__
- Die Variable $__ wird vom x-Befehl automatisch auf den Inhalt der letzten untersuchten Adresse gesetzt. Ihr Typ entspricht dem Format, in dem diese Daten ausgegeben wurden.
![]()
7.10 Prozessorregister
Sie können in Ausdrücken Bezug auf Prozessorregister nehmen, indem Sie Variablen verwenden, deren Namen mit '$' beginnen. Die Namen der Register unterscheiden sich von Maschine zu Maschine, benutzen Sie "info registers" um die auf Ihrer Hardware verwendeten Namen herauszufinden.
EDB hat vier Standard-Registernamen, die auf fast jeder Plattform in Ausdrücken verwendet werden können - wenn sie nicht mit den Vorschriften für Registernamen der verwendeten Maschine kollidieren.
- info registers
- Gibt die Namen und Inhalte aller Register (ausser Fliesskommaregister) des aktuellen Stackframes aus.
- info all-registers
- Gibt die Namen und Inhalte aller Register, auch der Fliesskommaregister, aus.
- info registers regname...
- Zeigt die Inhalte aller unter regname angegebenen Register an. Für regname kann jeder auf der Maschine gültige Name eingesetzt werden, mit oder ohne vorangestelltem '$'.
Die Registernamen $pc und $sp werden für das Programmzählerregister und den Stackpointer benutzt. $fp wird für ein Register verwendet, das einen Zeiger auf den aktuellen Stackframe enthält und $ps wird für das Register benutzt, das den Prozessorstatus enthält.
Sie können beispielsweise den Programmzähler (in hex) mit dem Befehl "p/x $pc" ansehen, die als nächstes auszuführende Instruktion mit "p/i $pc" ausgeben lassen oder mit "set $sp += 4" den Stackpointer um Vier erhöhen.
![]()
8 Symboltabellen-Kommandos
Mit den Kommandos in diesem Kapitel können Namen, Funktion und Typen von Programmvariablen bestimmt werden. Diese Information ist fester Bestandteil des Programms und wird durch die Programmausführung nicht beeinflusst. Die Symbolinformation wird der Symboltabelle der zum Debuggen ausgeführten Programmdatei entnommen.
- info address symbol
- Die Adresse für das Symbol symbol wird ausgegeben. Falls es sich um eine Registervariable handelt, wird das Register ausgegeben. Bei einer lokalen Variablen auf dem Stack wird der Offset zum Stackframe (Framepointer) ausgegeben.
- whatis exp
- Gibt den Datentype für den Ausdruck exp aus. Der Ausdruck wird nicht berechnet, damit entfallen auch eventuellen Seiteneffekte.
- ptype typename
- Gibt eine Beschreibung des Datentyps typename aus. Für Strukturen und Unions kann der Typename auch mit struct bzw. union eingeleitet werden.
- info types [regexp]
- Gibt eine kurze Beschreibung aller Typen deren Name den regulären Ausdruck regexp erfüllt (oder alle Typen falls kein Ausdruck angegeben wird) aus.
- info source
- Gibt den Namen der aktuellen Quelltextdatei aus. Die Datei die den Quelltext zur Funktion, die gerade ausgeführt wird, enthält, ist die aktuelle.
- info sources
- Gibt die Namen aller Quelltextdateien, für die die Programmdatei Debugginginformationen enthält, aus. In einer Liste werden alle Quelltextdateien ausgegeben, deren Symbolinformation schon gelesen wurde, in einer zweiten alle Dateien deren Information noch nicht gelesen wurde.
- info functions
- Gibt die Namen und Datentypen aller Funktionen aus.
- info functions regexp
- Gibt alle Funktionen aus, deren Namen ganz oder teilweise den regulären Ausdruck regexp erfüllt.
- info variables
- Gibt die Namen und Datentypen aller Variablen, die ausserhalb von Funktionen deklariert wurden, aus.
- info variables regexp
- Gibt alle Variablen (ausser lokale) aus, deren Namen ganz oder teilweise den regulären Ausdruck regexp erfüllt.
- printsyms filename
- Schreibt alle Debuggingsymbole in die Datei filename. Nur Symbole mit Debuggingdaten werden geschrieben.
![]()
9 Änderung des Programmablaufs
Wenn ein Fehler gefunden wurde ist es oft wünschenswert, diesen sofort zu beheben, um zu sehen ob das Programm danach korrekt abläuft. Mit EDB können Werte von Variablen oder Speicherstellen geändert werden, das Programm an einer anderen Stelle weitergeführt werden oder gar eine Funktion vorzeitig an die aufrufende Funktion zurückkehren.
![]()
9.1 Zuweisungen an Variablen
Um den Wert einer Variablen zu ändern, wird ein Ausdruck mit Zuweisung berechnet. Zum Beispiel:
print x=4
Diese Anweisung speichert den Wert 4 in der Variablen x und gibt danach den Wert des Zuweisungsausdruck aus.
Falls der Wert nicht ausgegeben werden soll, verwenden Sie das set-Kommando statt des print-Kommandos.
![]()
9.2 Programmadresse ändern
Normalerweise wird ein Programm mit dem continue-Kommando an der Stelle fortgesetzt, an der die Ausführung zuletzt gestoppt wurde. Mit den folgenden Kommandos kann die Ausführung an einer beliebigen Adresse fortgeführt werden:
- jump linespec
- Die Ausführung wird an der Stelle linespec fortgesetzt. Für linespec können die gleichen Parameter wie beim list-Kommando verwendet werden.
Das jump-Kommando ändert weder Stackpointer, Framepointer, den Inhalt des Speichers, noch den Inhalt von Registern. Es wird lediglich der Programmzähler geändert. Falls das Sprungziel nicht innerhalb der aktuellen Funktion liegt ergeben sich deshalb recht merkwürdige Resultate mit geringer Aussagekraft. Aus diesem Grund verlangt das jump-Kommando eine Bestätigung, falls das Sprungziel ausserhalb der aktuellen Funktion liegt.
- jump *address
- Die Ausführung wird an der Adresse address fortgesetzt.
![]()
9.3 Rückkehr von einer Funktion
- return [expression]
- Mit dem return-Kommando wird die Ausführung einer Funktion beendet. Das optionale Argument expression wird als Rückgabewert der Funktion benutzt.
![]()
9.4 Funktionsaufruf
- call expr
- Berechnet den Ausdruck expr, es erfolgt keine Anzeige, wenn die Funktion nichts zurückgibt.
Das call-Kommando ist lediglich eine Variante des print-Kommandos, bei der die Ausgabe von void Resultaten unterdrückt wird.
![]()
10 Dateifunktionen
- file filename
- filename ist das zu debuggende Programm. Die Datei kann auch einfach als Kommandozeilenparameter angegeben werden.
- load filename
- Das Programm filename wird auf das Targetsystem geladen. Um das Fortschreiten den Ladevorgangs beobachten zu können, wird die Anzahl der noch fehlenden Bytes ausgegeben. Der Kommandozeilenparameter '-L' hat den gleichen Effekt.
![]()
11 Erweiterte Funktionen
11.1 FLASH-Programmierung
EDB ab Version 1.04 enthält Routinen zur Programmierung von Flash-Speicherbausteinen auf der Targethardware im BDM-Betrieb. Diese Routinen unterstützen nur die Programmierung von AMD-Typen AM29F010 und AM29F040. Damit eine Programmierung auch auf fremder Hardware möglich ist, muss nach dem Start des Targetrechners das FLASH les- und schreibbar sein. Sollte es nicht der Fall sein, so können Sie die notwendige Initialisierung Ihrer Hardware in der Datei edb.ini vornehmen. Die dort angegebenen EDB-Befehle werden vor der Programmierung des FLASH ausgeführt.Die Programmierung kann entweder von der DOS-Kommandozeile aus gestartet werden, oder aber auch von der Eingabeshell des EDBs gesteuert werden.
Die Daten werden als Binärfile, z.B. a.out, erwartet. Ein eventuell vorhandener Header wird bei der Programmierung nicht weiter beachtet (wird aber mit programmiert). Für die Startadresse des Programms ist massgeblich Ihre Eingabe bestimmend. Geben Sie dem EDB keine Startadresse ein, so wird die Standardstartadresse benutzt. Diese Adresse liegt immer am Anfang des zweiten Blocks des FLASH. Somit ist ein evtl. vorhandener Bootloader im ersten Block geschützt und kann nicht versehentlich überschrieben werden. Bei den Rechnern von MCT ergeben sich somit folgende Startadressen:
Targetrechner Start AM29F010 Start AM29F040 ZWERG332 0x8000 0x10000 SC332 0x8000 0x20000 MEGA301 0x8000 0x20000 MEGA332 0x8000 0x20000 MEGA340 0x8000 0x20000 Programmierung über DOS-Kommandozeile
Eine Befehlszeile für den EDB zum Programmieren des FLASH könnte z.B. so aussehen:
edb -B -F a.out -T 0x12000 -target mega332
Es wird das Programm a.out an die Adresse 0x12000 auf den Targetrechner MEGA332 in das FLASH programmiert.
Programmierung über EDB-Shell
Befindet man sich bereits auf der Shell des EDBs, so kann man mit folgender Befehlssequenz den gleichen Effekt erreichen:
BDM-Betrieb einschalten: target bdm
Targetrechner festlegen: remotetarget mega332
Programmieren an die Adresse 0x12000: flash a.out 0x12000
![]()
11.2 Speichermanipulation
Im BDM-Betrieb stehen noch eine Reihe von Funktionen zur Verfügung, mit denen man den Speicher des Targetrechners modifizieren kann:
- bdm r address size
- Es wird der Inhalt der Speicherzelle von der Adresse address mit der Grösse size angezeigt. size kann b(yte), w(ord) oder l(ong)sein.
- bdm w address size value
- Es wird der Wert an der Stelle address mit der Grösse size auf den Wert von value gesetzt. size kann b(yte), w(ord) oder l(ong)sein.
- bdm d address cnt
- Es wird der Speicherbereich von address bis address + cnt angezeigt. Die Speicherzugriffe erfolgen im Wordformat.
- bdm f address cnt value
- Es wird der Speicherbereich von address bis address + cnt mit dem Wert value gefüllt. Die Speicherzugriffe erfolgen im Wordformat.
- bdm e
- Der Targetrechner wird resettet und das BDM-Interface zurückgesetzt.
Diese Funktionen dienen hauptsächlich der Initialisierung des Targetrechners, wenn eine ganz bestimmte Konstellation gewünscht wird. Auch ist es möglich hiermit schnell bestimmte Speicherzellen zu überprüfen.
![]()
12 Remote Debugging
12.1 Programminteraktion
Bei serieller Kommunikation kann auf der Debugger-Schnittstelle auch Programm-Eingabe und Ausgabe stattfinden. Auf der Konsole ist dabei die Programmkommunikation mit der Debuggerkommunikation gemischt, dies ist etwas gewöhnungsbedürftig. Mit dem userscreen-Kommando kann eine zusammenhängende Ausgabe der Programmkommunikation erfolgen. Bei der Programmkommunikation muss das '$' Zeichen vermieden werden. Das Programm samples/edb/interact.c demonstriert die Möglichkeiten.
![]()
12.2 Echtzeit
Falls Sie EDB verwenden, um ein Programm mit Echtzeitbedingungen zu debuggen, sollten Sie bedenken, dass einige Debuggerfunktionen die Ausführgeschwindigkeit des Targetprogramms zum Teil drastisch verlangsamen. Hier einige Tips um zeitkritische Applikationen zu debuggen:
- Verwenden sie bedingte Breakpoints statt Watchpoints. Wenn ein Watchpoint gesetzt ist läuft das Programm im Singlestep-Betrieb, nach jeder Instruktion wird der Wert der observierten Variable vom EDB gelesen, das Programm läuft dann mehr als 1000 mal langsamer. Bedingte Breakpoints stoppen dagegen nur, wenn das Programm die Breakpointposition abarbeitet.
- Setzen Sie Breakpoints erst nach zeitkritischen Programmteilen und analysieren Sie das Programm durch Statusvariablen, damit benötigt das System lediglich zusätzlich Zeit um die Statusvariablen zu setzten.
![]()
13 Anpassung
Wollen Sie EDB in Verbindung mit einer eigenen Hardware benutzen, sind je nach Betriebsart verschiedene Anpassungen nötig.
![]()
13.1 Background-Debugger
Dies ist die unproblematischste Art, fremde Hardware an EDB anzubinden, falls die CPU ihres Systems einen CPU32(+) Kern besitzt.
Softwareseitig sind keine Anpassungen erforderlich, jedoch muss die Hardware soweit initialisiert werden, dass EDB auf den vom Programm verwendeten Speicherbereich zugreifen kann. Diese Initialisierung kann auch mit den Speicherzugriffsbefehlen 'x' erfolgen. Programme die im ROM (EPROM, FLASH) liegen, können nicht geschrieben werden, da das Setzen von Breakpoints unmöglich ist. Diese schwerwiegende Einschränkung lässt sich durch ein Umkopieren ins RAM beim Programmstart umgehen. Vorlagen dafür befinden sich in libsrc/sysshare/srt0.h, das entsprechende Linkerscript ist rdb.ld.
Hardwareseitig muss das Target die Background-Debugger-Schnittstelle herausgeführt haben. Die genaue Anschlussbelegung des Adapters finden Sie im Kapitel Hardwareschnittstellen.
![]()
13.2 Serielle Schnittstelle
Die serielle Kommunikation erfordert ein Kommunikationsmodul auf der Targetseite. Die implementierten Targets verwenden die Bibliothek libsd.a zur Kommunikation, die Quellen dafür befinden sich in libsrc/libsd/serstub.c.
In speziellen Fällen kann es nützlich sein, das Verhalten dieses Moduls zu ändern. Folgende Makros können angepasst werden:
- GDBDEVICE
- Die Schnittstelle, über die die Kommunikation mit dem Hostsystem erfolgt, kann hiermit gesetzt werden, voreingestellt ist tty0.
- ENABLEDIAG
- Erlaubt die Ausgabe von Diagnosemeldungen über den internen Debuggerzustand. Standardmässig ist dies blockiert.
- DIAGDEVICE
- Die Schnittstelle, über die die Diagnosemeldungen ausgegeben werden, kann hiermit gesetzt werden, die Voreinstellung ist tty1. Es darf nicht die gleiche Schnittstelle wie für GDBDEVICE verwendet werden.
- USERECINTERRUPT
- Die Host-Kommunikation verwendet Interrupts, diese werden standardmässig freigegeben. Bei höheren Baudraten und um den Programmablauf zu unterbrechen ist der Interruptbetrieb erforderlich. Bei speziellen Problemstellungen kann die Verwendung von Interrupts abgeschaltet werden. Dann ist zu Prüfen, ob bei der Kommunikation Zeichen verloren gehen.
- LASTVECTOR
- Letzter Vektor, der umgelenkt wird. Die Voreinstellung ist 127.
- savevectors
- Dieses Array besitzt eine doppelte Funktion, zum einen zeigt jeder gesetzte Eintrag, dass der entsprechende Vektor umgelenkt werden soll, zum andern werden die alten Vektoren darin abgespeichert. Durch eine entsprechende Initialisierung kann der Anwender bestimmen, welche Vektoren abgefangen werden sollen.
NICO
Soll das Programm unter NICO ablaufen, ist eine eigene Anpassung von NICO für die entsprechende Hardware erforderlich.
Beliebiges Monitorprogramm
Existiert auf Ihrem Targetsystem ein Monitorprogramm, mit dem Sie Programme ins RAM laden und danach starten können, compilieren und linken Sie wie bei Verwendung von NICO. Bevor Sie EDB starten, muss das Programm, welches getestet werden soll, ins RAM geladen und danach gestartet werden.
ROM
Soll das Programm aus dem ROM heraus standalone ablaufen, muss der C-Start das Umkopieren ins RAM erledigen und danach ins RAM springen. Als Vorlage kann libsrc/sysshare/srt0.h verwendet werden, dieser C-Start erkennt auch automatisch ob für das RAM reloziert wurde. Der Sprung ins RAM ergibt sich unmittelbar aus der Relozierung beim Funktionsaufruf von main. Für die richtige Relozierung muss ein Linkerscript mit Textsegment auf RAM-Adressen erzeugt werden, als Vorlage dienen die rdb.ld Linkerscripte, dabei ist auf das Umsetzten des Resetvektors auf die ROM-Adresslage zu achten.
![]()
14 Hardwareschnittstellen
Background-Debugger
Der 16pol. Debug-Stecker enthält das von Motorola standardisierte 8pol. Background-Debugging-Interface auf den Pins 1 - 8, sowie den CPU-Clock und den JTAG Port. Falls ihr System nur den Motorola-Standardanschluss unterstützt, benötigen Sie die PCfant-Variante, die den CPU-Clock nicht benötigt. Bei dieser Variante muss das Targetsystem mit mindestens 8 MHz Systemtakt betrieben werden. Die Stromversorgung des PCfant erfolgt durch das Target, der zusätzliche Stromverbrauch ist zu berücksichtigen.
Pin Name Name Pin 1 GND BKPT* 2 3 GND FREEZE 4 5 RESET* DSI 6 7 VCC DSO 8 9 - CPUCLK 10 11 GND TCK 12 13 TDI TMS* 14 15 TDO VCC 16
- VCC
- +5V ±10% Stromversorgung für die Debuggerschaltung
- GND
- Masse
- RESET*
- Bidirektionaler Reset
- CPUCLK
- Interner CPU Takt zur Synchronisation der Debuggerschaltung
- BKPT*
- Breakpoint / DSCLK Eingang der CPU
- FREEZE
- Indikator, dass die CPU im Debug-Mode ist
- DSI
- Serieller Eingang
- DSO
- Serieller Ausgang
- TCK
- JTAG Port Clock Eingang
- TMS*
- JTAG Port Mode Eingang
- TDI
- JTAG Port Daten Eingang
- TDO
- JTAG Port Daten Ausgang
![]()
15 Bei Problemen
- Fehlermeldung "Communication Error: ... "
Es sind schwerwiegende Fehler bei der seriellen Kommunikation mit dem Target aufgetreten, die ein Wiederaufsetzen des Protokolls verhindern.
Abhilfe schafft hier nur ein erneutes Starten der Debug-Session (Reset des Targets und Neustart des EDB).
- Serielles Debugging mit 32KB RAM oder weniger
Das Programm vergrössert sich um die seriellen Debug-Funktionen, daher ist es meistens nicht möglich mit 32KB RAM zu arbeiten. Hier hilft nur eine Vergrösserung des RAMs.
- Breakpoints am Begin von for-Schleifen
Breakpoints werden generell auf den Anfang von Programmzeilen gesetzt, und dort steht bei for-Schleifen für gewöhnlich deren Initialisierung.
Deshalb sind diese Breakpoints nur ein einziges Mal erreichbar, da die Initialisierungssequenz der Schleife nur beim ersten Durchlauf aufgerufen wird.
- Breakpoints am Beginn von while-Schleifen
Ein ähnlicher Effekt wie bei den for-Schleifen tritt bei while-Schleifen auf, wenn beim Compilieren der Optimierer (Compilerswitch -O) aktiviert wurde, da dann der Wertevergleich vom Schleifenanfang an das Schleifenende verschoben wird und am Schleifenanfang nur noch die Initialisierungssequenz steht.
![]()
1Ein Hinweis für Leser der Originaldokumentation zum GNU-GDB: Laut diesem Dokument wird der Breakpoint bei Verwendung des tbreak-Befehls nur deaktiviert. Er wird aber definitiv gelöscht, also scheint es sich dort wohl um einen Tippfehler zu handeln.
2Die in der Original-GNU-Doku beschriebenen Funktionen handle und signal werden beim Remote-Debugging nicht unterstützt.
www.mct.de: Produkte: Software: EDB