Debuggen mit GDB (Gnu DeBugger) unter Eclipse bbdw58/anleit/  · Debuggen mit GDB (Gnu DeBugger)

  • View
    212

  • Download
    0

Embed Size (px)

Text of Debuggen mit GDB (Gnu DeBugger) unter Eclipse bbdw58/anleit/  · Debuggen mit GDB (Gnu DeBugger)

  • Debuggen mit GDB (Gnu DeBugger) unter Eclipse

    Boris Budweg, 16.11.2009

    Version 0.4 Abstract: Kleine Einfhrung in die Bedienung des GDB ber Eclipse und die Mglichkeiten eines Debuggers. Viele Screenshots und Hinweise auf weiterfhrende Informationen sollen die Neugier wecken. Erste Schritte .............................................................................................................................. 2

    Debug-Konfiguration anlegen und Debugger starten ............................................................ 2 Orientierung in der Debug-Perspektive.................................................................................. 5 Erster Lauf.............................................................................................................................. 6

    Fortgeschrittene .......................................................................................................................... 8 View: Breakpoints.................................................................................................................. 8 View: Disassembly................................................................................................................. 9 View: Registers .................................................................................................................... 11 Callstack, Springen in/aus Funktionen................................................................................. 12

  • 2

    Erste Schritte

    Debug-Konfiguration anlegen und Debugger starten

    Nachdem ein Projekt erstellt wurde, dieses vollstndig (ohne Fehler) gebaut wurde, ist es mglich, mit Hilfe eines Debuggers dem Ablauf des Programms zuzusehen und einzugreifen. Fr dieses Beispiel wird folgendes Programm verwendet:

    #include "stdio.h"

    #include"math.h"

    void main()

    {

    float zahl;

    printf("zahl eingeben:");

    scanf("%f", &zahl);

    if (zahl < 0)

    {

    printf("berechnung nicht mglich\n");

    } else

    {

    printf("quadratwurzel ist %f\n", sqrt(zahl) );

    }

    }

    Klicken Sie auf den kleinen Pfeil neben dem Kfer und selektieren Sie Debug Configurations:

    In dem neuen Fester selektieren Sie zunchst C/C++ Application, dann Neu (das leere Blatt mit dem + links darber):

  • 3

    Es wird eine neue Debug-Konfiguration erstellt, die blicherweise schon die korrekten Voreinstellungen hat:

    Nach einem Klick auf Debug gehts los! Diese Konfiguration mssen Sie 1x pro Projekt anlegen, dannach knnen Sie das Projekt immer debuggen, indem Sie direkt nach dem Kfer-Pfeil auf die gewnschte Konfiguration klicken:

    hnlich der C-Perspektive von Eclipse fr C-Programme, gibt es eine Debug-Perspektive zum Debuggen. Selektieren Sie daher im folgenden Fenster Remember und Yes.

  • 4

  • 5

    Orientierung in der Debug-Perspektive

    Bekannt in der Debug-Perspektive ist das Source-View aus der normalen C-Perspektive. Dort sehen Sie immer noch die geffneten C-Dateien (1). In diesem Fenster ist stets eine Zeile markiert (4). Diese gibt die aktuelle Position der Programmausfhrung an. Gesteuert wird die Programmausfhrung ber das Debug-View (2). Alle aktuellen Variablen und deren Werte sind unter dem Variablen-View (3) einsehbar. (Sollten Sie das Variablen-View nicht sehen, knnen Sie es einschalten unter Window Show View Variables)

    Parallel wird ein weiteres Konsolenfester extra fr das Programm geffnet, das vorerst leer ist (da das Programm noch nichts gemacht hat). Steuern knnen Sie den Programmablauf mit den Kontroll-Knpfen des Debug-Views:

    Von links nach rechts:

    Neustart des Debug-Laufes Normale Programmfortfhrung (bis zum nchsten Breakpoint) ([F8]) Pause (Programmablauf ist hier schon pausiert) Beenden des Debug-Laufes Disconnect (fr Debuggen eines Programms auf einem anderen Rechner, wird bei uns

    nicht verwendet) Einzelschritt (in eine Funktion hinein) ([F5]) Einzelschritt (ber eine Funktion hinweg) ([F6]) Sprung aus einer Funktion heraus (findet erst Verwendung, wenn Sie selbst

    Funktionen schreiben) ([F7])

  • 6

    Erster Lauf

    Fhren Sie nun Einzelschritte in Ihrem Programm aus (mit dem Knopf oder [F6]) Dabei knnen Sie die Position im Programm sowie die nderung der Variablen verfolgen. Sobald Sie an einem printf stehen und einen weiteren Einzelschritt ausfhren, knnen Sie danach im Konsolenfenster die Ausgaben des Programms beobachten:

    Schreiten Sie dagegen ber ein scanf, verschwindet die Positionsanzeige im Debugger so lange, bis Sie im Konsolenfenster etwas eingegeben haben. Erst dann knnen Sie weiter debuggen. Sehen Sie, wie sich die Zahl gendert hat?

    Je nachdem, ob Sie eine negative Zahle eingegeben haben, knnen Sie einen unterschiedlichen Verlauf des Programms feststellen, wenn Sie weiter schrittweise debuggen

    ( oder [F6]). Sie knnen brigens jederzeit hin- und herschalten zwischen Debug- und C-Perspektive, indem Sie die Knpfe oben rechts verwenden. Falls C/C++ nicht sichtbar ist, finden Sie es hinter dem Pfeil:

  • 7

    Nicht vergessen: Unabhngig davon, ob Sie die Perspektive wechseln, laufen Debugger und Programm weiterhin. Wenn Sie fertig gedebuggt haben, (d.h. wieder Programmcode ndern oder compilieren wollen) sollten Sie das Programm auf jeden Fall beenden (mit dem roten Stopp-Knopf, s.o.)!

  • 8

    Fortgeschrittene

    View: Breakpoints

    Breakpoints werden verwendet, um den Debugger an bestimmten Stellen im normalen Programmablauf zu aktivieren (nicht schon/nur am Programmanfang). Diese Funktion ist ntzlich, wenn das Programm lnger wird oder lngere Schleifen durchlaufen werden, deren Verlauf man sich nicht ansehen will. Breakpoints knnen an jede Zeile, die eine Anweisung enthlt, gesetzt werden. Wird diese Zeile nicht erreicht (z.B. weil der Zweig des IFs nicht durchlaufen wird), hlt der Debugger das Programm nicht an. Sie sollten also immer genau darauf achten, dass Sie den Breakpoint an der richtigen Stelle setzen, damit Sie den kritischen Punkt nicht verpassen zurckspulen kann der Debugger das Programm nmlich nicht. Setzen Sie den Breakpoint, indem Sie am Linken Rand der Zeile (links von der Zeilennummer, falls Sie diese aktiviert haben), doppelt klicken. Es erscheint dann ein kleiner Punkt an dieser Stelle und im Breakpoints-View wird die Zeile eingetragen:

    Wenn Sie nun Resume ([F8]) whlen, luft Ihr Programm normal weiter, bis es auf einen Breakpoint stt. Erst dort knnen Sie den Debugger wieder steuern. Dies ist ntzlich, wenn Sie nur an einer bestimmten Stelle im Programm debuggen wollen, ohne jeden einzelnen Schritt von Anfang an zu sehen. Sie knnen einen Breakpoint auch vorbergehend deaktivieren (ohne ihn zu lschen), indem Sie den Haken davor im Breakpoints-View entfernen. Eine Programmcodezeile ist brigens nur eine von von vielen Mglichkeiten, einen Breakpoint zu setzen. Im Internet gibt es mit Sicherheit noch einiges zu entdecken.

  • 9

    View: Disassembly

    Hier sehen Sie deutlich den Zusamenhang zwischen Ihrem Source-Code und dem vom Compiler generierten Assembler-Code (rechts ist blau der Original-Code angezeigt. Dies ist eine Zusatzfunktion von Eclipse; er gehrt natrlich nicht zum Assembler-Code):

    bringens: Wenn Sie unter den Projekteinstellungen die Optimierung beim Compilieren einstellen, wird der Assembler-Code merklich krzer:

    Die Optimierungsstufe des Compilers benutzt verschiedene Strategien, um Ihren Code zu verkrzen. Krzerer Code braucht weniger Speicher und wird schneller ausgefhrt, braucht aber auch lnger zum Compilieren und erschwert das Debuggen, da teilweise Befehle umgestellt werden (im Assembler-Code), und das Programm (im Source-Coode) dann nicht so abluft, wie Sie es erwarten. Wenn ein Programm fertig ist, d.h. ausgeliefert wird, schaltet man blicherweise den Optimierungsvorgang an und deaktiviert die Debugging-Informationen dann ist ein Debuggen mit Sourcecode allerdings nicht mehr mglich.

  • 10

  • 11

    View: Registers

    Die Hardware selbst kennt keine Variablen. Fr den Prozessor hat eine Variable keinen Namen, sondern nur noch eine Speicheradresse. Um mit den Speicherinhalten zu arbeiten, muss eine Kopie in einen bestimmten Bereich des Prozessors (sog. Register) angefertigt werden. Bei x86-Prozessoren heien die allgemen nutzbaren Register: eax, ebx, ecx, edx Auerdem gibt es ein paar weitere fr spezielle Aufgaben: esp = Stack Pointer fr die Stackverwaltung esi, edi = Quell-und Ziel-Index eip = Instruktions-Zeiger, zeigt auf den als nchstes auszufhrenden Befehl Die genannten sind alle Ganzzahlig. Der Prozessor bietet auch Register fr Fliekommawerte (st0, st1, st2,, st7). Moderne Prozessoren enthalten noch weitere Registerstze speziell fr Massendatenverarbeitung (XMM, MMX oder Altivec, etc) von Multimedia-Anwendungen. brigens: Der Instruktionszeiger ist gewissermaen eine Schwachstelle und Ziel von bestimmten Angriffsmethoden. Schafft es ein Angreifer hier eine Adresse einzuschleusen, an der der Code eines Computer-Virus liegt, fhrt der Prozessor unbemerkt ein schdliches Programm aus. Diese Attacke nennt man "Buffer Overflow".

  • 12

    Callstack, Springen in/aus Funktionen

    Findet ein Aufruf einer Funktion statt, fr die der Debugger auch Sourcecode zur Verfgung hat, knnen Sie: In diese Funktion hieneinspringen (Step into; [F5]), ber Sie hinweg (Step over; [F6]), oder aus ihr heraus (Step return; [F7]) Wenn Ihr Programm eine Funktion aufruft, deren Ausfhrung Sie verfolgen wollen, springen Sie hienein. Wenn Sie dann genug gesehen haben und erst wieder in der rufenden Funktion weiter debuggen wollen, springen Sie heraus. Wenn Ihr Programm eine Fu