Wikipedia · einfach zusammengefasst · Stand
Debugger
Funktionen eines Debuggers · die Steuerung des Programmablaufs, insbesondere durch Haltepunkte und die Einzelschritt-Verarbeitung von Befehlen · das Inspizieren …
Inhalt6 Abschnitte
Grundidee und Zweck
Ein Debugger ist ein Werkzeug, mit dem Fehler in Computersystemen diagnostiziert und gefunden werden. Er wird vor allem bei Programmen eingesetzt, kann aber auch die Hardware betreffen, die zur Ausführung eines Programms nötig ist. Debugging bezeichnet die Tätigkeit, solche Fehler zu untersuchen und aufzuspüren, entweder mit einem Debugger oder mit anderen Methoden.
Ein Debugger ist für die Softwareentwicklung wichtig, weil er sichtbar macht, was während der Programmausführung geschieht: welche Befehle ausgeführt werden, welche Daten im Speicher liegen, welche Registerwerte ein Prozessor hat und an welcher Stelle ein Programm unerwartet reagiert. Er kann auch beim Reverse Engineering helfen, also beim Verstehen fremder Programme durch Ablaufverfolgung und Untersuchung von Variablen.
Wichtige Funktionen
Zu den zentralen Funktionen eines Debuggers gehört die Steuerung des Programmablaufs. Dazu zählen besonders Haltepunkte und die Einzelschritt-Verarbeitung, bei der Befehle einzeln ausgeführt und untersucht werden können.
Ein Debugger kann Daten inspizieren, also sichtbar machen. Dazu gehören Register, aktueller Programmcode als Assembler oder Hochsprachenquelltext, Daten in festen und flüchtigen Speichern sowie fortgeschrittene Darstellungen wie Aufrufstapel, Ein-/Ausgabe-Register, Tabellen und Strukturen aus Hochsprachen.
Viele Debugger können Speicherinhalte verändern, zum Beispiel den Hauptspeicher, externe Ein-/Ausgabe-Zustände oder Register des Prozessorkerns. Je nach Debugger und Hardware können auch Rückmeldungen und Fehlerzustände des Zielsystems aufgefangen werden. Besonders wichtig sind Speicherzugriffsfehler, ungültige Opcodes und problematische Befehlsfolgen, etwa eine versuchte Division durch Null.
Ein Debugger ist häufig Teil einer Programm-Entwicklungsumgebung. Moderne Debugger können Änderungen am Quelltext während der Ausführung direkt übersetzen und danach das Programm fortsetzen; diese Technik wird als just in time debugging bezeichnet.
Arten des Debuggings
Grundsätzlich unterscheidet man zwischen Remote-Debugging und Debugging innerhalb des zu untersuchenden Prozessorsystems. Beim Remote-Debugging wird ein entferntes System untersucht. Eine Spezialform ist Remote-Debugging mit einer Simulation des Zielsystems, etwa durch eine Prozessor-Simulation und weitere simulierte Elemente.
Das Debuggen einer virtuellen Maschine liegt zwischen beiden Formen: Eine virtuelle Maschine kann sowohl wie eine lokale Anwendung als auch wie ein eigenständiges System betrachtet werden. Je nach Konzept sind beim Debugging sogar taktgenaue Bestimmungen des Laufzeitverhaltens möglich. Eine Simulation muss dabei nicht in Echtzeit ablaufen.
Bei Simulationen von Halbleitern wie ASIC, FPGA oder PLC werden sowohl Hardware- als auch Software-Simulationen verwendet. Diese Hilfsmittel sind über spezielle Debugger für Entwickler zugänglich.
Auf Assembler-Ebene ist einfache Fehlersuche bei einem dafür ausgelegten System jederzeit möglich. Manche Hochsprachen, zum Beispiel Skripte oder verschiedene BASIC-Varianten, lassen sich dagegen oft nur zeilenbasiert im Quelltext untersuchen. Erweiterte Funktionen wie das Auflösen von Symbolen, Strukturen und Funktionsnamen benötigen Symbol-Informationen, die in einer speziellen Datei oder in einem Binärprogramm eingebettet sein können, zum Beispiel als DWARF-Debug-Information.
Haltepunkte
Die wichtigste Fähigkeit eines Debuggers ist das Setzen von Haltepunkten. Ein Haltepunkt unterbricht die Ausführung eines Programms an einer bestimmten Stelle. Danach können Register und Speicher untersucht werden.
Am häufigsten werden Software-Haltepunkte genutzt. Dabei verändert der Debugger vorübergehend ein Byte im untersuchten Programm. Dieses Byte enthält dann die Anweisung, einen Breakpoint Interrupt auszulösen, sodass die Programmausführung an dieser Stelle anhält.
Software-Haltepunkte haben eine Einschränkung: Das untersuchte Programm darf seine eigene Integrität nicht prüfen, zum Beispiel durch eine Prüfsumme oder eine zyklische Redundanzprüfung. Malwareprogrammierer können diese Schwäche ausnutzen, um die Analyse eines Schadprogramms zu erschweren oder zu verhindern.
Hardware-Haltepunkte verändern das untersuchte Programm nicht. Sie sind direkt im Prozessor realisiert. Dafür stehen aber nur begrenzte Prozessorressourcen zur Verfügung, sodass nur eine begrenzte Anzahl solcher Haltepunkte möglich ist.
Viele Debugger erlauben bedingte Haltepunkte. Dabei wird zusätzlich zur Programmstelle ein boolescher Ausdruck angegeben. Der Debugger hält nur an, wenn die Stelle erreicht wird und der Ausdruck wahr ist. Um das zu prüfen, muss der Debugger die Programmausführung kurz unterbrechen und den Ausdruck auswerten.
Grenzen und Spezialfälle
In objektorientierten Laufzeitsystemen, bei paralleler Programmierung oder in verteilten Systemen ist es oft sehr schwierig oder praktisch unmöglich, eine genaue Programmabfolge zu bestimmen. Einige Entwicklungssysteme verzichten deshalb auf Laufzeit-Debugger, erlauben aber meist weiterhin Haltepunkte. Nach dem Programmstopp kann dann der Zustand aller Variablen analysiert werden.
Auch bei der Ausnahmebehandlung werden sogenannte Post-Mortem-Debugger eingesetzt. Sie untersuchen ein Programm nach einer Unterbrechung, die zum Beispiel durch einen Fehler erzwungen wurde.
Systematisch ähnelt ein Debugger den Mess- und Hilfsgeräten der Elektrotechnik und Elektronik, etwa Logik-Tester, Multimeter, Oszilloskop oder Signalgenerator. Wie diese Geräte hilft ein Debugger bei Inbetriebnahme, Überwachung und Fehlersuche in technischen Systemen.
Werkzeuge und Beispiele
Zur Fehlersuche gibt es zahlreiche Software-Werkzeuge. Genannt werden unter anderem gdb als GNU-Debugger und Unix-Werkzeug, DEBUG für MS-DOS, Microsoft Visual Studio mit integriertem Debugger und Remote Debugger, WinDbg und weitere Windows-Debugger, OllyDbg und x64dbg mit grafischer Oberfläche für Windows sowie valgrind zum Debuggen und Profilen von Linux-Programmen verschiedener Architekturen.
Weitere Beispiele sind IDA als Disassembler für viele Rechner-Architekturen mit Debuggern unter anderem für Arm-, MIPS-, m68k- und x86-/x64-Architektur, ltrace zur Anzeige dynamischer Bibliotheks- und Systemaufrufe unter Linux sowie strace, truss und DTrace zur Anzeige von Systemaufrufen.
Für eingebettete Systeme werden unter anderem iSYSTEM BlueBox mit winIDEA, Lauterbach TRACE32, PLS Universal Debug Engine UDE und SEGGER Ozone genannt. Als Hardware-Werkzeuge führt der Artikel JTAG, Logikanalysator und In-Circuit-Emulator (ICE) auf.