Breakpoints in Eclipse mit GNU ARM Plugin verwenden

Breakpoints sind für jeden Entwickler ein Segen. Irgendetwas am Code ist immer fehlerhaft und diese Fehler sieht man nicht. Bis man ihn gefunden hat, dann wundert man sich, dass er nicht sofort ins Auge gesprungen ist. Im Allgemeinen wird aber nur der Breakpoint ansich verwendet. Und jedes mal wenn der Prozessor am ihm vorbei kommt, hält er an. Auch wenn der Fehler erst im tausendsten Durchlauf einer Schleife auftritt, dann heißt es Resume (F8), Resume, Resume, .... und schon ist man einmal zu oft auf F8.
Um diese Situation etwas zu vereinfachen, gibt es beim GDB ein paar Möglichkeiten die Breakpoints bzw. deren Auslösen etwas zu einzuschänken. Dieser Artikel beschreibt zwei Möglichkeiten die Breakpoints zu parametrieren.

Allgemein, Breakpoints in Eclipse setzten

Breakpoints können in Eclipse wie in vielen anderen Entwicklungsumgebungen sehr einfach durch einen Doppelklick in der gewünschten Zeile gesetzt werden. In Eclipse muss dies links von der Zeile im Editor, links neben den Zeilennummern erfolgen. Es kann zur Vereinfachung auch die Tastenkombination Ctrl+Shift+B verwendet werden, um in der aktuellen Zeile (wo sich der Cursor befindet) einen Breakpoint zu setzen (oder zu löschen).

Dann erscheint ein kleiner blauer Punkt, der signalisiert, dass in dieser Zeile ein Breakpoint gesetzt ist.


Alternativ kann auch die rechte Maustaste verwendet werden. Dann erscheint ein Menü, in welchem durch Toggel Breakpoint ein Breakpoint gesetzt werden kann.


Zusätzlich gibt es in dem Menü die Möglichkeit, Breakpoints zu deaktivieren, sie aber prinzipiell an dieser Stelle zu behalten (Enable/Disable Breakpoint). Das ist insbesondere sinnvoll, wenn die Breakpoints aufwendig parametriert wurden. Siehe weitere Abschnitte dieses Blog-Eintrages.


Die Breakpoints können durch einen Doppellklick auf die Breakpoints auch wieder entfernt werden. Auch in diesem Fall (Breakpoint löschen) können wieder das Menü oder Ctrl+Shift+B verwendet werden.

Bedingungen für das Eintreten des Breakpoints

Die Wirkung von Breakpoints kann der Programmierer mit Bedingungen einschränken. Dabei wird der Aufruf nicht komplett unterlassen, sondern der Breakpoint wirkt und hält das Programm an. Dann wird durch den GDB die Bedingung abgeglichen und je nach Vergleichsergebnis sofort weiter gearbeitet oder eine richtige Unterbrechung eingeleitet. Die Bedingungen können einfache statische Vergleiche oder etwas komplexere Vergleiche zwischen Variablen oder Berechnungen sein (siehe Ende des Blog-Eintrages).
Diese Auswertung kostet zwar auch etwas Zeit ist aber für die viele Anwendungen keine kritische Einschränkung, da das Auslesen und Ausführen einer relativ einfachen Bedingung immer noch sehr schnell ist. Genaue Aussagen zu dem Zeitverhalten können an dieser Stelle allerdings nicht getroffen werden und können je nach Anwendung trotzdem den Programmfluß beeinflussen.

Das Setzen einer Bedingung erfolgt durch Auswahl des Menüs Breakpoint Properties eines Breakpoints (siehe oben) mit der rechten Maustaste.


Anschließend erscheint das Menü Breakpoint Properties (siehe folgende Abbildung).

Nun kann eine Bedingung eingegeben werden. Dabei können Variablen, die im jeweiligen Kontext gelten (also an dieser Stelle des Codes vorhanden sind) in der Bedingung verwendet werden. Hier im Beispiel soll die Variable seconds genau den Wert 10 haben um eine Unterbrechung (break) einzuleiten. Also ist der Wert Condition entsprechend seconds == 10.

Jetzt kann das Programm im Debug-Modus gestartet werden (Achtung, im Release-Modus funktioniert es nicht). Eclipse wechselt von selbst in die Debug-Ansicht (beim ersten Start eines Debug-Vorganges wird vom Nutzer erfragt, ob automatisch die Debug-Perspective geöffnet werden soll). 


Durch die Anwendung des Resume (F8) Buttons wird nun das Programm gestartet bzw. ausgeführt.

Im Beispiel wird das Blinky-Programm aus dem GNU ARM plugin verwendet, so dass jede Sekunde die Sekunden seit Programmstart in der Debug-Console angezeigt werden. Es ist ein Breakpoint mit der Bedingung seconds == 10 genau in die Zeile mit ++seconds gesetzt. Man erkennt, dass der Breakpoint zu einer Aktion führt, das Programm läuft aber weiter.
Wenn allerdings die gesetzte Bedingung erreicht ist (seconds == 10) dann hält der Debugger das Programm an, wie bei einem Breakpoint ohne weitere Bedingung. Es werden die relevanten Daten ausgelesen und beispielsweise im Variables-View die Werte für die aktuellen (lokalen) Variablen angezeigt.

Zum Debuggen kann nun wie gewohnt mit Resume, Step Into, Step Over usw. der Code weiter untersucht werden. Wichtig ist, dass der Variables-View nur bei einem anhalten aktualisiert wird (also nach jedem Step oder bei dem nächsten aktiven Breakpoint). Die Werte werden also nicht aktualisiert, falls die Bedingung für einen Beakpoint nicht gelten.

Ignorieren von Breakpoints, bevor sie gelten

Das ignorieren von Breakpoints ist eine weitere Eingrenzung der Programmunterbrechungen. Dabei wird ein Breakpoint so parametriert, dass dieser erst nach einer bestimmten Anzahl an möglichen Unterbrechungen wirklich zu einer Unterbrechung führt. Dies kann zum Beispiel verwendet werden, wenn Fehler erst nach einer bestimmten Laufzeit auftreten. So können beispielsweise die ersten 10 Breakpoint-Ereignisse ignoriert werden.

Dazu muss auf einen gesetzten Breakpoint mit der rechten Maustaste geklickt werden und der Menüpunkt Breakpoint Preferences aufgerufen werden.


Dann erscheint das Menü zu den Einstellungen des jeweiligen Breakpoints.

Über den Menüpunkt Ignore Count kann nun bestimmt werden, sie oft dieser Breakpoint ignoriert, also nicht ausgeführt werden soll, wenn der Programmfluß eigentlich den Breakpoint ausführen sollte. Beispielsweise soll der Breakpoint 5 mal ignoriert werden.

Anschließend wir die Programmausführung wieder im Debug-Modus gestartet. Das Programm ist wiederum (siehe oben) das Blinky-Programm aus dem GNU ARM plugin, wobei der Breakpoint wiederum auf ++seconds gesetzt ist. 

Jetzt können wir bereits im vorherigen Abschnitt beschrieben die einzelnen Debug-Möglichkeiten genutzt werden.

ACHTUNG: In der aktuellen Version sind die Einstellungen für Ignore Count nach einem Debug-Durchlauf auf dem Testsystem nicht mehr sichtbar. Dieser Parameter muss also vor JEDEM Debug-Durchlauf erneut gesetzt werden.

Kombination aus Breakpoint ignorieren und Bedingung

 Praktisch gesehen können auch beide Möglichkeiten kombiniert werden. So können eine Bedingung  und der Ignore Count gesetzt werden. Die möglichen sinnvollen Anwendungsfelder sind damit allerdings recht gering. Es funktioniert aber, siehe unten.

Und.

Auch können komplexe Bedingungen (Conditions) gesetzt werden. So soll der Breakpoint nur wirken wenn im obigen Beispiel des Blinky-Programmes gilt. (seconds*seconds) == (2*seconds) und ein Durchlauf ignoriert wird. Dabei wird dann für seconds == 0 kein Breakpoint gesetzt aber bei seconds == 2 wird dieser aufgerufen.

und.



Viel Spaß beim sinnvollen Setzten von Breakspoints.

Keine Kommentare:

Kommentar veröffentlichen