Finden Sie Bugs in Linux unter Verwendung von gdb

Um zu verstehen, wie Fehler in Linux mit gdb gefunden werden können, müssen Sie ein Beispiel sehen. Die Prozedur ist am einfachsten mit einem einfachen Beispiel zu zeigen, so dass dbgtst. c, ist ein künstliches Programm, das einen typischen Fehler enthält.

 #include statisches char buf [256]; void read_input (char * s); int main (void) {char * input = NULL; / * Nur ein Zeiger, kein Speicher für String * / read_input (Eingabe); / * Prozessbefehl. * / printf ("Sie haben eingegeben:% sn", Eingabe); / * ... _ * / return 0;} void read_input (char * s) {printf ("Befehl:"); gets (s);} 

Die Hauptfunktion dieses Programms ruft die read_input-Funktion auf, um eine Eingabezeile vom Benutzer zu erhalten. Die read_input-Funktion erwartet ein Zeichenarray, in dem sie zurückgibt, was der Benutzer eingibt. In diesem Beispiel ruft main read_input jedoch mit einem nicht initialisierten Zeiger auf - das ist der Fehler in diesem einfachen Programm.

Erstellen Sie das Programm mithilfe von gcc mit der Option -g:

 gcc -g -o dbgtst dbgtst. c 

Ignorieren Sie die Warnmeldung, dass die GET-Funktion gefährlich ist. Sie versuchen, den Nachteil dieser Funktion zu nutzen, um zu sehen, wie Sie mit gdb Fehler aufspüren können.

Um das Problem mit diesem Programm zu sehen, führen Sie es aus und geben Sie test an der Eingabeaufforderung Befehl:

 ein. / dbgtst Befehl: test Segmentierungsfehler 

Das Programm stirbt nach dem Anzeigen der Segmentierungsfehlermeldung ab. Für so ein kleines Programm wie dieses kann man die Ursache wahrscheinlich finden, indem man den Quellcode untersucht. In einer realen Anwendung wissen Sie jedoch möglicherweise nicht sofort, was den Fehler verursacht. Das ist, wenn Sie gdb verwenden müssen, um die Ursache des Problems zu finden.

Gehen Sie wie folgt vor, um gdb zu verwenden, um einen Fehler zu finden:

  1. Laden Sie das Programm unter gdb.

    Geben Sie beispielsweise gdb dbgtst ein, um ein Programm namens dbgtst in gdb zu laden.

  2. Starten Sie die Ausführung des Programms unter gdb, indem Sie den Befehl run eingeben. Wenn das Programm zur Eingabe auffordert, geben Sie einen Eingabetext ein.

    Das Programm schlägt wie zuvor fehl. Was passiert mit dem dbgtst-Programm?

     (gdb)  run  Startprogramm: / home / edulaney / swdev / dbgtst Befehl:  test  Programm empfangenes Signal SIGSEGV, Segmentierungsfehler. 0x400802b6 in gets () von / lib / tls / libc. damit. 6 (gdb) 
  3. Verwenden Sie den Befehl where, um festzustellen, wo das Programm gestorben ist.

    Für das Programm dbgtst liefert dieser Befehl diese Ausgabe:

     (gdb) wobei # 0 0x400802b6 in gets () aus / lib / tls / libc. damit. 6 # 1 0x08048474 in read_input (s = 0x0) bei dbgtst. c: 16 # 2 0x08048436 in main () bei dbgtst. c: 7 (gdb) 

    Die Ausgabe zeigt die Reihenfolge der Funktionsaufrufe. Der Funktionsaufruf # 0 - der jüngste - ist die C-Bibliotheksfunktion.Der Get-Aufruf stammt von der read_input-Funktion (in Zeile 16 der Datei dbgtst. C), die ihrerseits von der Hauptfunktion in Zeile 7 des dbgtst aufgerufen wird. c Datei.

  4. Verwenden Sie den Befehl list, um die Zeilen des verdächtigen Quellcodes zu überprüfen.

    In dbgtst können Sie mit Zeile 16 von dbgtst beginnen. c Datei, wie folgt:

     (gdb) Liste dbgtst. c: 16 11 Rückkehr 0; 12} 13 void read_input (char * s) 14 {15 printf ("Befehl:"); 16 bekommt (s); 17} 18 (gdb) 

    Nachdem Sie sich diese Auflistung angesehen haben, können Sie feststellen, dass das Problem möglicherweise darin besteht, wie read_input aufgerufen wird. Dann listen Sie die Zeilen um Zeile 7 in dbgtst auf. c (woher der Aufruf von read_input stammt):

     (gdb) list dbgtst. c: 7 2 statisches char buf [256]; 3 void read_input (char * s); 4 int main (ungültig) 5 {6 char * input = NULL; / * Nur ein Zeiger, kein Speicher für String * / 7 read_input (input); 8 / * Prozessbefehl. * / 9 printf ("Sie haben eingegeben:% sn", Eingabe); 10 / * ... * / 11 gibt 0 zurück; (gdb) 

    An dieser Stelle können Sie das Problem auf die Variable input eingrenzen. Diese Variable ist ein Array, kein NULL-Zeiger (dh null).