Durch Eclipse wird Debugging von Linux-Systemen so komfortabel wie ein Tool vom Hersteller

Remote-Debugging mit Eclipse

5. März 2010, 11:17 Uhr | Joachim Kroll
Diesen Artikel anhören

Fortsetzung des Artikels von Teil 1

Verbindung zum Zielsystem

Debugging Eclipse
Bild 3. Eine Debugging-Sitzung wird gestartet. Die Ziel-Hardware wird durch die IP-Adresse des Boards ausgewählt.

Verbindung zum Zielsystem über ssh

Mit dem Hauptprogramm aus der ssh- Suite, ssh, baut Eclipse nach dem Kopieren der Datei erneut eine Terminal- Verbindung auf, über die Befehle per Textzeile übermittelt werden. Innerhalb dieser Session wird dann der gdbserver gestartet, der seinerseits in der Debugging-Umgebung das Programm ausführt. Über die ssh-Shell kann Eclipse das zu debuggende Programm mit Aufrufparametern und Umgebungsvariablen versorgen. Die Ausgaben auf dieser Shell können in einem Eclipse-Fenster eingesehen werden, sodass beispielsweise Trace-Meldungen aus dem Programm nicht verlorengehen. Alle erforderlichen und oben beschriebenen Protokolle setzen auf TCP/IP auf. Für das Debugging ist also lediglich eine Netzwerkverbindung erforderlich. Auf die serielle Schnittstelle kann verzichtet werden. Ebenso sind JTAG-Adapter oder ähnliches verzichtbar. Gelegentlich haben Embedded- Systeme kein Ethernet.

In diesem Fall kann auf das Netzwerk via USB zurückgegriffen werden. Damit scp und ssh mit dem Embedded- Board funktionieren, ist ein entsprechender Dienst auf dem Embedded- Linux-System erforderlich. Der Standard-SSH-Server OpenSSH kann auf vielen Embedded-Linux-Systemen problemlos integriert werden, sofern er nicht sowieso schon Bestandteil des Standardumfangs ist. Für kleinere, etwa MMU-lose Systeme gibt es mit dem ssh-Server Dropbear auch eine leichtgewichtige Alternative. Das erforderliche Passwort bei der Authentifizierung ohne Public/Private Key kann komfortabel, aber unsicher in Eclipse gespeichert werden. Das nimmt das lästige Eintippen das Passwortes ab, öffnet aber ein Einfallstor für mögliche Angreifer. Es empfiehlt sich also, vor der Auslieferung des Embedded-Linux-Systems die Passwörter wenigstens zu ändern oder besser die Authentifizierung per Benutzername/ Passwort zu deaktivieren oder – wenn möglich – den ssh-Server ganz zu entfernen.

passend zum Thema

Debugging Eclipse
Bild 4. Ein Breakpoint wurde erreicht. Die Programmausgaben stehen im untersten Fenster.

Schritt für Schritt oder „Step-over“

Während der Debugging-Sitzung mit Eclipse kann der Entwickler im Programmcode zeilengenau Breakpoints setzen oder von Zeile zu Zeile springen (Bild 4). Der Programmverlauf kann so „live“ mitverfolgt werden. Der Wert jeder Variablen lässt sich betrachten und analysieren. Funktionsaufrufe können ebenso analysiert oder die Funktionen schnell ohne Debugging durchschritten werden. Dieses so genannte Step-over empfiehlt sich immer dann, wenn es sich um Funktionsaufrufe in Libraries handelt, die nicht debuggt werden sollen oder können. Oftmals stehen für diese Libraries auch keine Debugging-Symbole zur Verfügung, sodass sinnhaftes Debugging hier nicht ohne weiteres möglich ist.

Bei populären Libraries etwa aus der Open-Source-Welt ist die Wahrscheinlichkeit für einen Bug in der Library eher gering, aber natürlich nicht ausgeschlossen. Die Erfahrung hat gezeigt, dass bei Fehlern, die innerhalb von Libraries auftreten, oftmals falsch initialisierte Datenstrukturen oder unbeabsichtigte Modifikationen am Stack oder Code die Ursache sind. Zur Analyse übergebener Strukturen ist die Analyse der Aufrufparameter mit Eclipse komfortabel möglich (Bild 5). Die eigentliche Library-Funktion sollte dann per Step-over ohne Unterbrechnung durchschritten werden. Der Entwickler kann zu jedem Zeitpunkt die Debugging-Sitzung abbrechen und den Quellcode editieren.

Nur sehr wenige Klicks oder Tastenkürzel sind erforderlich, um das modifizierte Programm neu zu übersetzen, auf das Zielsystem zu kopieren und dort eine neue Debugging-Sitzung zu beginnen. Der Durchlauf der Compile-Test- Zyklen ist damit optimal kurz, und der Entwickler kann sich voll auf den Code konzentrieren und diesen systematisch prüfen oder nach Programmfehlern (Bugs) suchen. Bei massiv falschen Speicherzugriffen unterbricht der Debugger sofort, nicht jedoch bei nur geringfügigem Abweichen vom legalen Speicherbereich. Diese unzulässigen Speichermodifikationen sind eine Klasse von Fehlern, die nicht selten Grund für schwere Programmfehler sind.

Debugging Eclipse
Bild 5. Bei der Analyse von Library-Funktionen ist es sinnvoll, die Korrektheit der Aufrufparameter zu überprüfen. Eclipse gibt dazu den aktuellen Variableninhalt aus.

Speicherfehler entdecken mit DUMA und valgrind

Die unzulässige Modifikation (Schreibbefehl) bleibt dabei zunächst unentdeckt, da sie noch kein unmittelbares Fehlverhalten bedeutet. Wird jedoch später wieder von der betroffenen Speicherstelle gelesen, so führt der dann vorgefundene und unerwartete Wert typischerweise zu einem schweren Fehler. Es ist nun relativ leicht, das Lesen des falschen Wertes zu analysieren. Der eigentliche Fehler aber, also das Schreiben an die falsche Stelle, kann jedoch nicht immer mit den Mitteln von Eclipse und gdb analysiert werden. Unterstützung bei Problemen dieser Klasse erfährt der Entwickler durch Libraries wie DUMA (Detect Unintended Memory Access) oder durch die Nutzung von Hostside-Debuggern wie valgrind.

DUMA umklammert jeden angeforderten Speicherbereich so, dass jeder Zugriff außerhalb des angeforderten Bereiches zwangsläufig und sofort zu einem Abbruch führt. Diese Abbrüche lassen sich dann gut mit Eclipse und gdb analysieren und damit schnell auflösen. Zur Nutzung von DUMA muss der Entwickler lediglich mittels Linker-Befehl die Library einbauen. arm-linux-gnueabi-gcc -g –o memerror memerror.c -lduma Der Speicher-Debugger „valgrind“ steht typischerweise nicht auf Embedded- Linux-Systemen zur Verfügung. Ausnahmen bilden hier nur die Power- Architektur und x86-Systeme. Dennoch kann Software, die etwa auf einem ARM eingesetzt werden soll, auch mit Hostside-Debuggern analysiert werden. Es muss die Software aber mit dem Host-Compiler des Entwicklungsrechners übersetzt werden. Danach kann das zu prüfende Programm mit valgrind automatisch instrumentiert und gestartet werden. Die Intrumentierung der Software erfolgt nach der Übersetzung, unmittelbar vor dem Start. Spezielle Compiler-Schalter sind also nicht erforderlich.

Dennoch ist es hilfreich, mit dem Compiler-Schalter „-g“ zu übersetzen, sodass valgrind in der Lage ist, die Quelldatei und die Code-Zeile auszugeben. Diese Angaben vereinfachen das Auffinden von Problemen im Quellcode. Zusätzlich sollte auf Optimierungen mit „-O1“, „-O2“ oder „-O3“ verzichtet werden. Nach Erzeugung des binären Programms wird valgrind wie folgt gestartet: valgrind –leak-check=full testapp Durch die Instrumentierung analysiert valgrind jede Operation des Programms und zeigt Fehler und potentielle Probleme an, wie etwa die Nutzung uninitialisierten Speichers, Fehlzugriffe in ungültige Speicherbereiche und Speicherlecks (siehe Kasten „Debugging mit valgrind“). Grundsätzlich empfiehlt es sich, jede Software mit valgrind zu überprüfen, um die Qualität zu erhöhen. Die Instrumentierung durch valgrind verlangsamt die Ausführung in ganz erheblichem Maße, sodass das Debugging mit valgrind durchaus eine Geduldsprobe darstellen kann. Eine Investition, die sich jedoch fast immer lohnt.

Studieren geht über Probieren

Die Werkzeuge gdb, Eclipse, DUMA und valgrind sind hilfreiche und mächtige Debugging-Tools, die die Entwicklung von Software für Embedded- Linux-Systeme erheblich vereinfachen. Die intensive Nutzung von Debuggern führt schnell zu funktionierender Software, ist aber nicht ganz unkritisch. Es besteht die Gefahr, dass der Entwickler sich nur auf seinen Debugger und seine eigenen Tests verlässt und den Blick und das Verständnis für das Umfeld, in dem seine Ergebnisse später Verwendung finden, vernachlässigt. Insbesondere bei komplizierter Algorithmik kann ein Debugger dazu verleiten, eine Lösung für ein Problem nur durch Herumprobieren zu finden. Ein Durchdringen des Algorithmus ist hierfür nicht erforderlich. Entsprechend gering ist die Qualität des dadurch entstehenden Codes. Ein Debugger kann die Lösung eines Problems in einem Programm beschleunigen, weil die fehlerhafte Stelle schneller lokalisiert wird.

Bei der eigentlichen Ausarbeitung der Lösung ist ein Debugger jedoch wenig hilfreich. Hierzu muss der Entwickler den Code sowie den Grund des Fehlers genau verstehen und dann eine saubere Lösung erarbeiten. Mit einem Schnellschuss, der im Debugger keine Fehler mehr zeigt, ist das Problem oftmals nur verschoben und tritt später möglicherweise verschärft wieder auf. Vollständige Testszenarien und ein Code-Review des Fixes mit Kollegen oder bei Open-Source-Software mit der Community steigern die Qualität des Fixes erheblich und sollten daher obligatorisch sein. Die Nutzung von Debuggern direkt aus den Source-Code heraus ist mit den Software-Paketen Eclipse, ssh und gdb für Embedded-Linux-Entwickler erheblich vereinfacht worden. Der Arbeitsablauf ist damit der gleiche wie innerhalb einer herstellerspezifischen Entwicklungsumgebung mit Hardware-Debugger. Einsparungen sind jedoch auf der Seite des Linux-Entwicklers möglich, da dieser keinen teuren Hardware-Debugger und keine kostenpflichtigen Software-Lizenzen braucht. Der Setup von Eclipse und die erforderliche Konfiguration von Toolchain, Debugger und ssh-Verbindung sind von nicht geringer Komplexität, brauchen jedoch nur einmalig durchgeführt zu werden. Embedded Linux Board Support Packages von emlix in der Professional Edition enthalten immer ein konfiguriertes Eclipse und beschreiben die erforderlichen Schritte für das Remote-Debugging detailliert.

Thomas Brinker studierte an der Technischen Universität Berlin Technische Informatik. Seit 2005 ist er bei der emlix GmbH in Göttingen als Embedded Linux Systemengineer beschäftigt und dort an der hardwarenahen Entwicklung von Produkten für die Medizintechnik, Automatisierungstechnik und Datentechnik beteiligt. Er arbeitet im Bereich der Kernel- und Treiberentwicklung und leitet seit 2006 die Emlix-Niederlassung in Berlin.tb@emlix.com


  1. Remote-Debugging mit Eclipse
  2. Verbindung zum Zielsystem

Lesen Sie mehr zum Thema


Jetzt kostenfreie Newsletter bestellen!

Weitere Artikel zu emlix GmbH

Weitere Artikel zu Entwicklungswerkzeuge