26.02.2014 Aufrufe

Linux-Magazin Clean Linux (Vorschau)

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

Know-how<br />

www.linux-magazin.de Embedded Debugging 09/2013<br />

86<br />

Abbildung 1: Remote Debugging lässt sich über die Kommandozeile oder ein IDE wie Eclipse bewerkstelligen.<br />

informieren. Die Technik heißt, in Anlehnung<br />

an den Funktionsaufruf in C, meist<br />

einfach nur Printf. Sie hat den Nachteil,<br />

dass der Entwickler das Programm anpassen<br />

und die zu beobachtenden Teile<br />

vor dem Übersetzen kennen muss. Dafür<br />

steht der schlichte Ansatz fast immer zur<br />

Verfügung.<br />

Die Ausgabe muss nicht über einen Bildschirm<br />

laufen, für den die Zielsysteme oft<br />

keine Schnittstelle mitbringen, sondern<br />

kann über einen Ethernet-Port oder eine<br />

serielle RS232-Verbindung erfolgen. Fehlt<br />

auch diese, etwa bei sehr einfachen Systemen,<br />

lässt sich eine LED einsetzen, die<br />

ein Muster blinkt, das den Programmfortschritt<br />

anzeigt.<br />

Gemeinsam ist diesen Ansätzen, dass sie<br />

keine explizite Kopplung des Zielsystems<br />

mit dem Entwicklungssystem voraussetzen,<br />

sondern dass der Entwickler seine<br />

Schlüsse aus den Ausgaben des Zielsystems<br />

zieht, die er dann auf dem Entwicklungssystem<br />

umsetzt.<br />

Remote Debugging<br />

Eine komfortablere Fehlersuche schließt<br />

einen Debugger wie GDB [1] ein. Mit<br />

dessen Hilfe unterbricht der Entwickler<br />

die Ausführung seines Programms an bestimmten<br />

Stellen, verfolgt sie Quelltextzeile<br />

für Quelltextzeile weiter, kontrolliert<br />

und manipuliert den Inhalt von Registern<br />

und Variablen.<br />

In der klassischen Software-Entwicklung<br />

finden sowohl die Analyse als auch die<br />

Ausführung des Programms auf dem Entwicklungssystem<br />

statt, das dem Zielsys-<br />

tem sehr stark ähnelt. Eine Entwicklungsumgebung<br />

(Abbildung 1) unterstützt den<br />

Programmierer und erleichtert die Analyse.<br />

Dies setzt voraus, dass die untersuchte<br />

Software auf demselben Rechner<br />

läuft wie der Debugger beziehungsweise<br />

die Entwicklungsumgebung.<br />

Weil dies bei eingebetteten Systemen oft<br />

nicht zutrifft, kommt Remote Debugging<br />

zum Einsatz. Dabei startet der Entwickler<br />

auf dem Zielsystem eine Helfer-Applikation,<br />

mit der sich der Debugger des<br />

Entwicklungssystems verbindet, zum<br />

Beispiel über Ethernet oder die serielle<br />

RS232-Schnittstelle.<br />

Im Falle von GDB führt der Zielrechner<br />

einen GDB-Server aus, bei dem sich der<br />

GDB-Client auf dem Entwicklungssystem<br />

anmeldet. Der Client leitet nun Anweisungen<br />

an die Serverinstanz auf dem<br />

Zielsystem weiter, um zum Beispiel das<br />

untersuchte Programm anzuhalten oder<br />

die Registerinhalte auszulesen. Zugleich<br />

steuert der Programmierer die Anwendung<br />

auf diesem Weg.<br />

Der Server setzt die Anweisungen um<br />

und schickt die Resultate an das Entwicklungssystem<br />

zurück. Dessen Debugger<br />

Cross-Toolchain<br />

Bei der Entwicklung für eingebettete Systeme,<br />

die zum Beispiel ARM-Prozessoren verwenden,<br />

kann der Entwickler die systemeigene Compiler-Toolchain<br />

(Assembler, Compiler, Linker<br />

und Debugger) des Entwicklungssystems nicht<br />

verwenden, um Quelltext in Binärcode für das<br />

Zielsystem zu übersetzen.<br />

Hier kommt eine Cross-Toolchain zum Einsatz,<br />

die auf dem Entwicklungssystem läuft, während<br />

übernimmt dann die rechenintensiven<br />

Aufgaben. Er gleicht Assembler-Instruktionen<br />

mit bestimmten Quelltextzeilen ab<br />

und ordnet Variablen richtig zu.<br />

Debugging über Kreuz<br />

Unterscheiden sich die Architekturen von<br />

Entwicklungs- und Zielsystem, versteht<br />

der Debugger des Entwicklungssystems<br />

weder die Assembler-Instruktionen des<br />

Gegenübers, noch kennt er dessen Register.<br />

Das verhindert ein direktes Auswerten<br />

von Variablen und Zuordnen von<br />

Instruktionen zum Quelltext.<br />

Dieses Problem löst ein so genannter<br />

Cross-Debugger, der Bestandteil der<br />

Cross-Toolchain ist. Er lässt sich ebenfalls<br />

auf dem Entwicklungssystem ausführen,<br />

versteht jedoch die Assembler-Instruktionen<br />

des jeweiligen Zielsystems. Das<br />

macht es unter anderem möglich, mit<br />

Hilfe von Remote Debugging ein ARM-<br />

Programm auf einem x86-System zu untersuchen<br />

(Abbildung 2).<br />

Im Falle von Android stellt Google beispielsweise<br />

Entwicklungsumgebungen<br />

für Smartphone- und Tablet-Entwickler<br />

bereit. Letztere können beim Remote Debugging<br />

kaum noch unterscheiden, ob<br />

die Anwendung auf dem Endgerät oder<br />

dem Rechner des Entwicklers läuft. Auf<br />

dem Entwicklungssystem arbeitet dabei<br />

ein Emulator.<br />

DIY: Remote Debugging<br />

Die eben vorgestellte Form des Remote<br />

Debugging setzt voraus, dass das Zielsystem<br />

mehrere Programme zugleich<br />

ausführen kann, also mindestens das<br />

zu untersuchende Programm und ein<br />

Hilfsprogramm wie den GDB-Server. Das<br />

funktioniert zum Beispiel problemlos,<br />

wenn auf dem Zielsystem ein Betriebssystem<br />

wie etwa <strong>Linux</strong> läuft.<br />

der von ihr erzeugte Binärcode nur auf dem<br />

Zielsystem funktioniert. Gleiches gilt für den<br />

Debugger in der Cross-Toolchain, der nur den<br />

Binärcode des Zielsystems versteht.<br />

Cross-Toolchains auf GCC-Basis lassen sich bei<br />

den meisten <strong>Linux</strong>-Distributionen für verschiedene<br />

Zielarchitekturen aus der Paketverwaltung<br />

heraus installieren oder durch entsprechende<br />

Skripte einfach selbst übersetzen.

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!