Immer unterwegs
Sobald Sie das Programm angehalten haben, gibt es drei wichtige Befehle, um es wieder in Gang zu setzen. Das Kürzel »n« (Next) führt die nächste Anweisung aus und kehrt zum GDB-Prompt zurück. »s« (Step) schreitet zur nächsten Anweisung, im Gegensatz zu »n« auch dann, wenn sie sich innerhalb einer Funktion befindet. Das Kommando »c« (Continue) setzt die Programmausführung bis zum Erreichen des nächsten Breakpoints oder bis zum Programmende fort.
Die von den Distributionen installierten Standardbibliotheken wurden üblicherweise ohne Debugging-Informationen kompiliert, deshalb lassen sie sich nicht mit dem Befehl »s« schrittweise abarbeiten. Allerdings gibt es dafür zum Teil separate Pakete, zum Beispiel bei Fedora »glibc-debuginfo- Version.rpm«.
Wenn Sie das Programm mit dem Parameter »23« starten, berechnet es die Stückelung für 23 Cent. Die Funktion »CalcChangeFor()« in Listing 1 berechnet dazu zuerst die nötige Anzahl an 2-Euro-Münzen (200 Cent). Bei einem Betrag von 23 Cent sollte die Funktion merken, dass sie dafür keine 2-Euro-Münzen braucht. Sie bleibt aber in der Prüfschleife hängen.
Um den Grund herauszufinden, sehen Sie sich die Variablen an. Die Symbol-Informationen enthalten alle Details der Variablen, einschließlich des Typs und des Gültigkeitsbereichs (lokal oder global). Der Befehl »p« oder »print« gibt den Wert einer Variablen im aktuellen Gültigkeitsbereich aus. Haben Sie sich schrittweise mit »s« zu Zeile 17vorgearbeitet, geben Sie Folgendes ein:
(gdb) print val
$1 = 200
(gdb) p i
$2 = 23
Der Wert hinter dem »$«-Symbol erhöht sich mit jedem »print«-Befehl. Eine Variable dauerhaft beobachten ist Aufgabe des Kommandos »display« (Tabelle 3):
(gdb) display val
1: val = 200
(gdb) disp i
2: i = 23
Während Sie sich anschließend mit »s« weiter durch den Code bewegen, beobachten Sie die Werte, um zu verstehen, warum die Schleife nicht endet.
|
|
|
Befehl
|
Beschreibung
|
|
b [ Dateiname:] Zeilennummer
|
Setzt Breakpoint in Zeile
|
|
b [ Dateiname:] Funktion
|
Setzt Breakpoint am Anfang einer Funktion
|
|
b [ Dateiname:] Zeilennummer if expr
|
Setzt bedingten Breakpoint
|
|
watch Ausdruck
|
Fügt Watchpoint für Variable/Ausdruck hinzu (Abkürzung: »wa«)
|
|
info break
|
Listet Breakpoints und Watchpoints auf
|
|
delete
|
Löscht alle Breakpoints
|
|
delete [N]
|
Breakpoint-Nummer #N (gem. Ausgabe von »info break«)
|
|
disable [N]
|
Deaktivert Breakpoint [N] (oder alle, falls [N] nicht spezifiziert)
|
|
|
|
Befehl
|
Beschreibung
|
|
print [/F] [ Ausdruck]
|
Gibt Ausdruck sofort aus, z. B.: /x = hex, /d = dez, /u
= ohne Vorzeichen, /o = okt, /t = bin, /c = char, /f = float; /F ist ein optionales Format
|
|
display [/F] [ Ausdruck]
|
Gibt Ausdruck vor jedem Befehlsprompt aus
|
|
display
|
Listet Werte für alle Ausdrücke
|
|
undisplay
|
Entfernt alle Ausdrücke aus der Displayliste
|
|
undisplay [N]
|
Entfernt bestimmten Ausdruck aus der Liste (wie mit dem Display- Befehl angegeben)
|
Der Fehler im Beispielprogramm kommt an Hand der Variablen »i« zum Vorschein: Sie sollte kleiner werden, wird aber hochgezählt, denn im Zählerabschnitt der »for«-Schleife in Zeile 16 steht »i++« statt »i--«.
|
Breakpoints werden auch dann fortlaufend nummeriert, wenn Sie einen wieder gelöscht haben. Wenn Sie zum Beispiel mit zwei Breakpoints (1 und 2) beginnen und dann »delete 2« eingeben, erhält der nächste Breakpoint trotzdem die Nummer 3. So bleiben Ihnen bei Änderungen Verwechslungen zwischen alt und neu erspart. Das Gleiche gilt für Display-Variablen und Watchpoints.
|
Erbarmungslos - Teil II
Nach der Korrektur des Fehlers kompilieren Sie das Programm neu. Dazu müssen Sie zwar den Debugger nicht beenden, aber den laufenden Prozess, denn sonst erhalten Sie beim Linken die Fehlermeldung, dass die Datei noch in Benutzung ist:
(gdb) kill
Kill the program being debugged? (y or n) y
Nach dem Kompilieren des Programms, nutzen Sie den Befehl »file«, um es wieder in den Speicher zu laden. Da Sie den Debugger in diesem Fall zuvor nicht beendet haben, bleiben alle Breakpoints erhalten - das spart vor allem bei größeren Projekten viel Zeit:
(gdb) file change
Load new symbol table from "change"?
(y or n) y
Reading symbols from "change"...done.
(gdb) r
Beachten Sie, dass der »r«-Befehl das letzte Argument beibehält, sodass Sie auf die Eingabe des Parameters wie bei »r 23« verzichten können. Wenn Sie sich nun schrittweise durch die Schleife tasten, stellen Sie fest, dass die Zählervariable »i« korrekt heruntergezählt wird. Sie können jetzt alle Breakpoints mit »delete« entfernen (Tabelle 2) und das Programm weiterlaufen lassen.
Nach ungewöhnlich langer Verzögerung gibt der Debugger einen Speicherzugriffsfehler aus und kehrt zurück zur Eingabeaufforderung (siehe Listing 4). Es gibt also einen weiteren Bug. Als Erstes müssen Sie feststellen, wo genau das Programm momentan steht. Dazu sehen Sie sich den Call Stack (oder Backtrace) an, der die aufgerufenen Funktionen sowie deren Parameter anzeigt.
Diese Ausgabe aus Listing 5 zeigt, dass der Algorithmus in einer rekursiven Schleife steckt. Das Programm ruft dieselbe Funktion immer wieder mit dem gleichen Parameter auf. Daher wird die Abbruchbedingung (»cent==0«) niemals ausgelöst.
Program received signal SIGSEGV, Segmentation fault.
0x080485a7 in CalcChangeFor (cent=23) at change.c:19
19 CalcChangeFor(cent - i*val);
|
(gdb) backtrace
#1 0x08048505 in CalcChangeFor (cent=23) at change.c:19
#2 0x08048505 in CalcChangeFor (cent=23) at change.c:19
#3 0x08048505 in CalcChangeFor (cent=23) at change.c:19
#4 0x08048505 in CalcChangeFor (cent=23) at change.c:19
.....
|
(gdb) b 15
Breakpoint 2 at 0x8048554: file change.c, line 15.
(gdb) r
Starting program: /home/steev/code/change 23
Breakpoint 2, CalcChangeFor (cent=23) at change.c:15
15 val = coins[i];
|
Wenn Sie den Debugger neu starten - da Sie die Datei nicht verändert haben, reichen dazu die Befehle »kill« und »run« - und Breakpoints für jeden rekursiven Aufruf für »CalcChangeFor()« setzen, erkennen Sie, dass der Wert von »cent« unverändert bleibt, denn »i*val = 0«.
| Whitepaper |
|
Open Source Datenintegration in der Praxis: Fallstudien und Anwendungsbeispiele (Folge 2)
Der zweite Teil des Open Source Datenintegration in der Praxis: Fallstudien und Anwendungsbeispiele White Papers beleuchtet anhand weiterer ausgewählter Case Studies die Implementierung von Open Source Datenintegration in der Praxis und benennt die daraus resultierenden Vorteile.
Download PDF (Registrierung erforderlich)
|
|
Usage Landscape Enterprise Open Source Data Integration
Die Nachfrage nach Datenintegrationslösungen für Unternehmen ist zunehmend gestiegen und vor allem das Interesse an Open Source Technologien wird immer größer. Doch wie und von wem werden Open Source Datenintegrationslösungen genutzt und welches Nutzungsverhalten lässt sich daraus ableiten? Das vorliegende White Paper präsentiert die Erfahrungswerte von über 1000 Open Source Nutzern und liefert fundierte Antworten auf diese Fragen.
Download PDF (Registrierung erforderlich)
|
Dieser Online-Artikel kann Links enthalten, die auf nicht mehr vorhandene Seiten verweisen. Wir ändern solche "broken links"
nur in wenigen Ausnahmefällen. Der Online-Artikel soll möglichst unverändert der gedrucken Fassung entsprechen.
|