GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie man C-Programme unter Linux mit gdb debuggt

Unabhängig davon, wie erfahren Sie als Programmierer sind, kann keine von Ihnen entwickelte Software vollständig fehlerfrei sein. Das Identifizieren und Beheben von Fehlern ist daher eine der wichtigsten Aufgaben im Softwareentwicklungszyklus. Während es viele Möglichkeiten gibt, Fehler zu identifizieren (Testen, Selbstüberprüfung des Codes und mehr), gibt es spezielle Software - sogenannte Debugger - die Ihnen helfen, genau zu verstehen, wo das Problem liegt, damit Sie es leicht beheben können.

Wenn Sie ein C/C++-Programmierer sind oder Software mit den Programmiersprachen Fortran und Modula-2 entwickeln, werden Sie froh sein zu wissen, dass es einen hervorragenden Debugger namens GDB gibt, mit dem Sie Ihren Code ganz einfach auf Fehler und andere Probleme debuggen können. In diesem Artikel werden wir die Grundlagen von GDB besprechen, einschließlich einiger nützlicher Funktionen/Optionen, die es bietet.

Aber bevor wir fortfahren, ist es erwähnenswert, dass alle Anweisungen und Beispiele in diesem Artikel auf Ubuntu 14.04LTS getestet wurden. Der im Tutorial verwendete Beispielcode ist in C-Sprache geschrieben; die von uns verwendete Befehlszeilen-Shell ist bash (Version 4.3.11); und die von uns verwendete GDB-Version ist 7.7.1.

Grundlagen des GDB-Debuggers

Einfach gesagt, mit GDB können Sie einen Blick in ein Programm werfen, während das Programm ausgeführt wird, sodass Sie leichter erkennen können, wo genau das Problem liegt. Wir werden die Verwendung des GDB-Debuggers anhand eines funktionierenden Beispiels im nächsten Abschnitt besprechen, aber vorher werden wir hier einige grundlegende Punkte besprechen, die Ihnen später helfen werden.

Erstens müssen Sie, um Debugger wie GDB erfolgreich verwenden zu können, Ihr Programm so kompilieren, dass der Compiler auch Debugging-Informationen erzeugt, die von Debuggern benötigt werden. Im Fall des gcc-Compilers, den wir später in diesem Tutorial zum Kompilieren des C-Beispielprogramms verwenden werden, müssen Sie beispielsweise -g verwenden Befehlszeilenoption beim Kompilieren Ihres Codes.

Um zu erfahren, was die Handbuchseite des gcc-Compilers über diese Befehlszeilenoption sagt, gehen Sie hierher.

Der nächste Schritt besteht darin, sicherzustellen, dass Sie GDB auf Ihrem System installiert haben. Wenn dies nicht der Fall ist und Sie sich auf einem Debian-basierten System wie Ubuntu befinden, können Sie das Tool einfach mit dem folgenden Befehl installieren:

sudo apt-get install gdb

Für die Installation auf einer anderen Distribution gehen Sie hierher.

Nun, sobald Sie Ihr Programm so kompiliert haben, dass es für das Debuggen bereit ist und GDB auf Ihrem System vorhanden ist, können Sie Ihr Programm mit dem folgenden Befehl im Debugging-Modus ausführen:

gdb [prog-executable-name]

Während dies den GDB-Debugger initiiert, wird Ihre ausführbare Programmdatei zu diesem Zeitpunkt nicht gestartet. Dies ist die Zeit, in der Sie Ihre Debugging-bezogenen Einstellungen definieren können. Sie können beispielsweise einen Haltepunkt definieren, der GDB anweist, die Programmausführung bei einer bestimmten Zeilennummer oder Funktion anzuhalten.

Um Ihr Programm tatsächlich zu starten, müssen Sie den folgenden gdb-Befehl ausführen:

run

Es ist erwähnenswert, dass Sie, wenn Ihr Programm die Übergabe einiger Befehlszeilenargumente erfordert, diese hier angeben können. Zum Beispiel:

run [arguments]

GDB bietet viele nützliche Befehle, die sich beim Debuggen als nützlich erweisen. Wir werden einige davon im Beispiel im nächsten Abschnitt besprechen.

GDB-Nutzungsbeispiel

Jetzt haben wir eine grundlegende Vorstellung von GDB sowie seiner Verwendung. Nehmen wir also ein Beispiel und wenden das Wissen dort an. Hier ist ein Beispielcode:

#include <stdio.h>

int main()
{
int out = 0, tot = 0, cnt = 0;
int val[] = {5, 54, 76, 91, 35, 27, 45, 15, 99, 0};

while(cnt < 10)
{
out = val[cnt];
tot = tot + 0xffffffff/out;
cnt++;
}

printf("\n Total = [%d]\n", tot);
return 0;
}

Im Grunde nimmt dieser Code also jeden im Array „val“ enthaltenen Wert, weist ihn der Ganzzahl „out“ zu und berechnet dann „tot“, indem er den vorherigen Wert der Variablen und das Ergebnis von „0xffffffff/“ summiert. raus.“

Das Problem hierbei ist, dass beim Ausführen des Codes der folgende Fehler erzeugt wird:

$ ./gdb-test 
Floating point exception (core dumped)

Um den Code zu debuggen, wäre der erste Schritt also, das Programm mit -g zu kompilieren. Hier ist der Befehl:

gcc -g -Wall gdb-test.c -o gdb-test

Lassen Sie uns als Nächstes GDB ausführen und ihm mitteilen, welche ausführbare Datei wir debuggen möchten. Hier ist der Befehl dafür:

gdb ./gdb-test 

Nun, der Fehler, den ich erhalte, ist „Gleitkomma-Ausnahme“, und wie die meisten von Ihnen vielleicht bereits wissen, wird er durch n % x verursacht, wenn x 0 ist. In diesem Sinne habe ich einen Haltepunkt an der Zeilennummer gesetzt 11, wo die Teilung stattfindet. Dies geschah auf folgende Weise:

(gdb) break 11

Beachten Sie, dass '(gdb)' der Prompt des Debuggers ist, ich habe gerade den Befehl 'break' geschrieben.

Nun habe ich GDB gebeten, die Ausführung des Programms zu starten:

run

Als der Haltepunkt zum ersten Mal erreicht wurde, zeigte GDB Folgendes in der Ausgabe:

Breakpoint 1, main () at gdb-test.c:11
11 tot = tot + 0xffffffff/out;
(gdb)

Wie Sie in der obigen Ausgabe sehen können, hat der Debugger die Zeile angezeigt, in der der Haltepunkt gesetzt wurde. Lassen Sie uns nun den aktuellen Wert von „out“ ausgeben. Dies kann auf folgende Weise erfolgen:

(gdb) print out
$1 = 5
(gdb)

Wie Sie sehen können, wurde der Wert „5“ gedruckt. Also im Moment ist alles in Ordnung. Ich habe den Debugger gebeten, die Ausführung des Programms bis zum nächsten Haltepunkt fortzusetzen, was mit dem Befehl 'c' erledigt werden kann.

c  

Ich machte diese Arbeit weiter, bis ich sah, dass der Wert von 'out' Null war.

...
...
...
Breakpoint 1, main () at gdb-test.c:11
11 tot = tot + 0xffffffff/out;
(gdb) print out
$2 = 99
(gdb) c
Continuing.

Breakpoint 1, main () at gdb-test.c:11
11 tot = tot + 0xffffffff/out;
(gdb) print out
$3 = 0
(gdb)

Um zu bestätigen, dass dies genau das Problem ist, habe ich dieses Mal den Befehl 's' (oder 'step') von GDB anstelle von 'c' verwendet. Der Grund dafür ist, dass ich nur Zeile 11, in der die Programmausführung derzeit angehalten ist, ausführen wollte, um zu sehen, ob an dieser Stelle ein Absturz auftritt.

Folgendes ist passiert:

(gdb) s

Program received signal SIGFPE, Arithmetic exception.
0x080484aa in main () at gdb-test.c:11
11 tot = tot + 0xffffffff/out;

Ja, wie durch die hervorgehobene Ausgabe oben bestätigt, wurde hier die Ausnahme ausgelöst. Die endgültige Bestätigung kam, als ich erneut versuchte, den Befehl 's' auszuführen:

(gdb) s 

Program terminated with signal SIGFPE, Arithmetic exception.
The program no longer exists.

Auf diese Weise können Sie also Ihre Programme mit GDB debuggen.

Schlussfolgerung

Wir haben hier nur an der Oberfläche gekratzt, da GDB viele Funktionen bietet, die Benutzer erkunden und verwenden können. Sehen Sie sich die Manpage von GDB an, um mehr über das Tool zu erfahren, und versuchen Sie, es immer dann zu verwenden, wenn Sie etwas in Ihrem Code debuggen. Der Debugger ist mit einer gewissen Lernkurve verbunden, aber die harte Arbeit lohnt sich.


Linux
  1. So erstellen Sie einen Linux-Benutzer mit Ansible

  2. Linux – Wie debuggt man ein Suspend-to-ram-Problem unter Linux?

  3. So starten Sie Linux über die Befehlszeile neu

  4. Wie beendet man einen Prozess unter Linux mit dem Befehl?

  5. Wie man ein C-Programm mit gdb in 6 einfachen Schritten debuggt

So erstellen Sie Screenshots unter Linux mit Scrot

So benennen Sie Dateien über die Befehlszeile in Linux um

So entfernen Sie Programme, die mit GNU Stow in Linux aus der Quelle installiert wurden

So listen Sie Dateisysteme in Linux mit Lfs auf

So formatieren Sie Shell-Programme mit Shfmt unter Linux

So verwenden Sie GDB zum Debuggen von Programmen in Ubuntu 20.04