GNU-Debugger - GNU Debugger

GNU-Debugger
GDB Bogenschütze Fisch von Andreas Arnez.svg
GDB-screenshot.gif
Entwickler GNU-Projekt
Erstveröffentlichung 1986 ; vor 35 Jahren ( 1986 )
Stabile Version
11.1 / 13. September 2021 ; Vor 1 Tag ( 2021-09-13 )
Repository
Geschrieben in C
Betriebssystem Unix-ähnlich , Windows
Typ Debugger
Lizenz GPLv3
Webseite www .gnu .org / Software / GDB

Der GNU Debugger ( GDB ) ist ein portabler Debugger , der auf vielen Unix-ähnlichen Systemen läuft und für viele Programmiersprachen funktioniert , darunter Ada , C , C++ , Objective-C , Free Pascal , Fortran , Go und teilweise andere.

Geschichte

GDB wurde erstmals 1986 von Richard Stallman als Teil seines GNU- Systems geschrieben, nachdem sein GNU Emacs "angemessen stabil" war. GDB ist freie Software, die unter der GNU General Public License (GPL) veröffentlicht wird. Es wurde dem DBX- Debugger nachempfunden , der mit Berkeley-Unix- Distributionen geliefert wurde .

Von 1990 bis 1993 wurde es von John Gilmore betreut . Jetzt wird es vom GDB-Lenkungsausschuss gepflegt, der von der Free Software Foundation ernannt wird .

Technische Details

Merkmale

GDB bietet umfangreiche Möglichkeiten, die Ausführung von Computerprogrammen zu verfolgen und zu verändern . Der Benutzer kann die Werte der internen Variablen des Programms überwachen und ändern und sogar Funktionen unabhängig vom normalen Verhalten des Programms aufrufen .

GDB-Zielprozessoren (ab 2003) umfassen: Alpha , ARM , AVR , H8/300 , Altera Nios/Nios II , System/370 , System 390 , X86 und seine 64-Bit-Erweiterung X86-64 , IA-64 "Itanium" , Motorola 68000 , MIPS , PA-RISC , PowerPC , SuperH , SPARC und VAX . Zu den weniger bekannten Zielprozessoren , die in der Standardversion unterstützt werden, gehören A29K , ARC , ETRAX CRIS , D10V , D30V , FR-30 , FR-V , Intel i960 , 68HC11 , Motorola 88000 , MCORE , MN10200 , MN10300 , NS32K , Stormy16 und Z8000 . (Neuere Versionen werden einige davon wahrscheinlich nicht unterstützen.) GDB hat Simulatoren für noch weniger bekannte Zielprozessoren wie M32R oder V850 einkompiliert .

GDB wird noch aktiv weiterentwickelt. Ab Version 7.0 umfassen die neuen Funktionen Unterstützung für Python- Skripting und ab Version 7.8 auch GNU Guile- Skripting. Seit Version 7.0 ist Unterstützung für "reversibles Debugging" verfügbar, das es einer Debugging-Sitzung ermöglicht, rückwärts zu gehen, ähnlich wie das Zurückspulen eines abgestürzten Programms, um zu sehen, was passiert ist.

Remote-Debugging

GDB bietet einen "Remote"-Modus, der häufig beim Debuggen von eingebetteten Systemen verwendet wird. Remote-Betrieb ist, wenn GDB auf einem Computer ausgeführt wird und das zu debuggende Programm auf einem anderen ausgeführt wird. GDB kann mit dem entfernten "Stub", der das GDB-Protokoll versteht, über ein serielles Gerät oder TCP/IP kommunizieren. Ein Stub-Programm kann durch Verlinken mit den entsprechenden Stub-Dateien erstellt werden, die mit GDB bereitgestellt werden und die die Zielseite des Kommunikationsprotokolls implementieren. Alternativ kann gdbserver verwendet werden, um das Programm aus der Ferne zu debuggen, ohne es in irgendeiner Weise ändern zu müssen.

Der gleiche Modus wird auch von KGDB zum Debuggen eines laufenden Linux-Kernels auf Quellebene mit gdb verwendet. Mit KGDB können Kernel-Entwickler einen Kernel genauso debuggen, wie sie Anwendungsprogramme debuggen. Es ermöglicht das Platzieren von Breakpoints im Kernel-Code, das schrittweise Durchlaufen des Codes und das Beobachten von Variablen. Auf Architekturen, in denen Hardware-Debugging-Register verfügbar sind, können Watchpoints gesetzt werden, die Breakpoints auslösen, wenn spezifizierte Speicheradressen ausgeführt oder darauf zugegriffen werden. KGDB erfordert einen zusätzlichen Computer, der über ein serielles Kabel oder Ethernet mit dem zu debuggenden Computer verbunden ist . Unter FreeBSD ist es auch möglich, mit FireWire Direct Memory Access (DMA) zu debuggen .

Grafische Benutzeroberfläche

Der Debugger hat keine eigen enthält grafisch Benutzeroberfläche und standardmäßig eine Kommandozeilen - Schnittstelle , obwohl es einen enthält Text Benutzeroberfläche . Dafür wurden mehrere Frontends entwickelt, wie UltraGDB , Xxgdb , Data Display Debugger (DDD), Nemiver , KDbg , der Xcode Debugger, GDBtk/Insight und HP Wildebeest Debugger GUI (WDB GUI). IDEs wie Codelite , Code::Blocks , Dev-C++ , Geany , GNAT Programming Studio (GPS), KDevelop , Qt Creator , Lazarus , MonoDevelop , Eclipse , NetBeans und Visual Studio können mit GDB kommunizieren. GNU Emacs hat einen "GUD-Modus" und Tools für VIM existieren (zB clewn). Diese bieten ähnliche Funktionen wie Debugger in IDEs.

Einige andere Debugging-Tools wurden entwickelt, um mit GDB zu arbeiten, z. B. Speicherleckdetektoren .

Einbauten

GDB verwendet einen Systemaufruf namens ptrace (der Name ist eine Abkürzung für "Process Trace"), um die Ausführung eines anderen Prozesses zu beobachten und zu steuern und den Speicher und das Register des Prozesses zu untersuchen und zu ändern. Eine Liste gängiger gdb-Befehle und entsprechender ptrace-Aufrufe ist unten aufgeführt:

  • (gdb) start : PTRACE_TRACEME – macht Eltern zu einem Tracer (von einem verfolgten aufgerufen)
  • (gdb) Attache PID: PTRACE_ATTACH – an einen laufenden Prozess anhängen
  • (gdb) stop: kill(child_pid, SIGSTOP) (oder PTRACE_INTERRUPT)
  • (gdb) weiter: PTRACE_CONT
  • (gdb) Inforegister: PTRACE_GET(FP)REGS(ET) und PTRACE_SET(FP)REGS(ET)
  • (gdb) x : PTRACE_PEEKTEXT und PTRACE_POKETEXT

Ein Breakpoint wird implementiert, indem ein Befehl an einer gegebenen Speicheradresse durch einen anderen speziellen Befehl ersetzt wird. Die Ausführung des Breakpoint-Befehls verursacht SIGTRAP.

Beispiele für Befehle

gdb program Debug "Programm" (aus der Shell)
run -v Führen Sie das geladene Programm mit den Parametern aus
bt Backtrace (falls das Programm abgestürzt ist)
info registers Alle Register löschen
disas $pc-32, $pc+32 Zerlegen

Eine Beispielsitzung

Betrachten Sie den folgenden in C geschriebenen Quellcode :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

size_t foo_len( const char *s )
{
  return strlen( s );
}

int main( int argc, char *argv[] )
{
  const char *a = NULL;

  printf( "size of a = %lu\n", foo_len(a) );

  exit( 0 );
}

Bei Verwendung des GCC- Compilers unter Linux muss der obige Code mit dem -gFlag kompiliert werden , um geeignete Debug-Informationen zu der generierten Binärdatei einzuschließen, sodass sie mit GDB überprüft werden kann. Angenommen, die Datei, die den obigen Code enthält, heißt example.c, der Befehl für die Kompilierung könnte wie folgt lauten:

$ gcc example.c -Og -g -o example

Und die Binärdatei kann jetzt ausgeführt werden:

$ ./example
Segmentation fault

Da der Beispielcode bei der Ausführung einen Segmentierungsfehler erzeugt , kann GDB verwendet werden, um das Problem zu untersuchen.

$ gdb ./example
GNU gdb (GDB) Fedora (7.3.50.20110722-13.fc16)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /path/example...done.
(gdb) run
Starting program: /path/example

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400527 in foo_len (s=0x0) at example.c:8
8	  return strlen (s);
(gdb) print s
$1 = 0x0

Das Problem tritt in Zeile 8 auf und tritt beim Aufrufen der Funktion auf strlen(weil ihr Argument s, ist NULL). Je nach Implementierung von strlen ( inline oder nicht) kann die Ausgabe unterschiedlich sein, zB:

GNU gdb (GDB) 7.3.1
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu".
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /tmp/gdb/example...done.
(gdb) run
Starting program: /tmp/gdb/example

Program received signal SIGSEGV, Segmentation fault.
0xb7ee94f3 in strlen () from /lib/i686/cmov/libc.so.6
(gdb) bt
#0  0xb7ee94f3 in strlen () from /lib/i686/cmov/libc.so.6
#1  0x08048435 in foo_len (s=0x0) at example.c:8
#2  0x0804845a in main (argc=<optimized out>, argv=<optimized out>) at example.c:16

Um das Problem zu beheben, muss die Variable a(in der Funktion main) einen gültigen String enthalten. Hier ist eine feste Version des Codes:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

size_t foo_len( const char *s )
{
  return strlen(s);
}

int main( int argc, char *argv[] )
{
  const char *a = "This is a test string";

  printf( "size of a = %lu\n", foo_len(a) );

  exit( 0 );
}

Das erneute Kompilieren und erneute Ausführen der ausführbaren Datei in GDB liefert jetzt ein korrektes Ergebnis:

GDB druckt die Ausgabe von printfauf dem Bildschirm und informiert den Benutzer dann, dass das Programm normal beendet wurde.

Siehe auch

Verweise

Externe Links

Dokumentation

Tutorials