Gdb

Aus VDR Wiki
(Unterschied zwischen Versionen)
Wechseln zu: Navigation, Suche
(Artikel angelegt)
 
(Mit Beispielen erweitert)
Zeile 18: Zeile 18:
  
 
Die meisten Distributionen haben diese Kernelspeicherabzug, die durch eine Einstellung gesperrt, so mußt sie zuerst reaktiviert werden. "ulimit -c unlimited" macht dies für die gegenwärtige Shell und alle Prozesse, die von ihm begonnen werden. Überprüfe die Bash-Man-Seite, wenn du mehr über den ulimit Befehl wissen möchtest.  
 
Die meisten Distributionen haben diese Kernelspeicherabzug, die durch eine Einstellung gesperrt, so mußt sie zuerst reaktiviert werden. "ulimit -c unlimited" macht dies für die gegenwärtige Shell und alle Prozesse, die von ihm begonnen werden. Überprüfe die Bash-Man-Seite, wenn du mehr über den ulimit Befehl wissen möchtest.  
 +
 +
# ulimit -c unlimited
  
 
Nächstes Mal wenn die Anwendung mit einem segfault abstürzt, siehst du, daß die Anzeige "Segmentation fault", in  
 
Nächstes Mal wenn die Anwendung mit einem segfault abstürzt, siehst du, daß die Anzeige "Segmentation fault", in  
 
"Segmentation fault (core dumped)" geändert wurde. Und eine eine Datei "core" oder "core.pid" im aktuellen Verzeichnis gestellt wurde. Anmerkung: Du benötigst auch Schreibberechtigung für das aktuelle Verzeichnis, andernfalls wird keine Datei erstellt.  
 
"Segmentation fault (core dumped)" geändert wurde. Und eine eine Datei "core" oder "core.pid" im aktuellen Verzeichnis gestellt wurde. Anmerkung: Du benötigst auch Schreibberechtigung für das aktuelle Verzeichnis, andernfalls wird keine Datei erstellt.  
  
Jetzt ist es Zeit, gdb zu starten, um zu sehen, was genau geschah. Das erste Argument für gdb sollte die abgestürzte Anwendung, das zweite der Kernelspeicherabzug sein, der wegen des Abbruchs geschrieben wurde. gdb listet viele Informationen auf und begrüßt dich mit einer "(gdb)" Aufforderung, wenn es abgeschlossen ist. Die nützlichste Information für einen Entwickler ist ein sogenanntes Stacktrace. Schreibe "bt" in der Aufforderung um gdb aufzufordern, um einen Stacktrace zu auszugeben, welches du dann zum Entwickler verschicken kannst. Mit "quit" verlässt man gdb.  
+
Jetzt ist es Zeit, gdb zu starten, um zu sehen, was genau geschah. Das erste Argument für gdb sollte die abgestürzte Anwendung, das zweite der Kernelspeicherabzug sein, der wegen des Abbruchs geschrieben wurde.  
 +
 
 +
# gdb vdr /tmp/core.2841
 +
 
 +
gdb listet viele Informationen auf und begrüßt dich mit einer "(gdb)" Aufforderung, wenn es abgeschlossen ist. Die nützlichste Information für einen Entwickler ist ein sogenanntes Stacktrace.  
 +
 
 +
Copyright 2004 Free Software Foundation, Inc.
 +
GDB is free software, covered by the GNU General Public License, and you are
 +
welcome to change it and/or distribute copies of it under certain conditions.
 +
...
 +
Core was generated by `/opt/vdr-1.4/bin/vdr -l 1 6 -v /video/vdr -L /opt/vdr-1.4/lib -s /opt/vdr-1.4/b'.
 +
Program terminated with signal 11, Segmentation fault.
 +
...
 +
Reading symbols from /usr/lib/libstdc++.so.5...done.
 +
Loaded symbols for /usr/lib/libstdc++.so.5
 +
Reading symbols from /lib/tls/libm.so.6...Reading symbols from /usr/lib/debug/lib/tls/libm-2.3.2.so...done.
 +
..
 +
#0  0xb7e06090 in malloc_consolidate () from /lib/tls/libc.so.6
 +
(gdb)
 +
 
 +
Schreibe "bt" in der Aufforderung um gdb aufzufordern, um einen Stacktrace zu auszugeben, welches du dann zum Entwickler verschicken kannst. Mit "quit" verlässt man gdb.  
 +
 
 +
(gdb) bt
 +
#0  0xb7e06090 in malloc_consolidate () from /lib/tls/libc.so.6
 +
#1  0xb7e05f6e in _int_free () from /lib/tls/libc.so.6
 +
#2  0xb7e04dcb in free () from /lib/tls/libc.so.6
 +
#3  0x081066b6 in ~cFrame (this=0x8f17110) at ringbuffer.c:352
 +
#4  0x08106bc2 in cRingBufferFrame::Delete (this=0x8f1b988, Frame=0x8f17110) at ringbuffer.c:411
 +
#5  0x08106c4b in cRingBufferFrame::Drop (this=0x8f1b988, Frame=0x8f17110) at ringbuffer.c:421
 +
#6  0x08106a15 in cRingBufferFrame::Clear (this=0x8f1b988) at ringbuffer.c:374
 +
#7  0x08106958 in ~cRingBufferFrame (this=0x8f1b988) at ringbuffer.c:366
 +
#8  0x080b1f0c in ~cDvbPlayer (this=0x8f179a0) at dvbplayer.c:276
 +
#9  0x080b3e01 in cDvbPlayerControl::Stop (this=0x8f163a0) at dvbplayer.c:775
 +
#10 0x080e0fc8 in cReplayControl::ProcessKey (this=0x8f163a0, Key=kBlue) at menu.c:4154
 +
#11 0x081372a3 in main (argc=30, argv=0xbffffac4) at vdr.c:1022
 +
(gdb) quit
  
 
===Andere Weisen, gdb zu benutzen ===
 
===Andere Weisen, gdb zu benutzen ===
  
Du kannst eine Anwendung unter Steuerung des gdb vollständig startem. Das tun gerechte Art „gdb Anwendung“. In der gdb Eingabeaufforderung verwendet „run Parameter“, um die Anwendung zu starten. Wenn die Anwendung ein Signal empfängt, wird gdb die Eingabeauforderung zeigen um Befehle dazu einzugeben. Du kannst jederzeit Strg-C drücken, um eine gdb Eingabeauforderung zu erhalten.  
+
Du kannst eine Anwendung unter Steuerung des gdb vollständig startem. Das tun gerechte Art '''gdb Anwendung'''. In der gdb Eingabeaufforderung verwendet '''run Parameter''', um die Anwendung zu starten. Wenn die Anwendung ein Signal empfängt, wird gdb die Eingabeauforderung zeigen um Befehle dazu einzugeben. Du kannst jederzeit Strg-C drücken, um eine gdb Eingabeauforderung zu erhalten.  
  
 
====Die nützlichsten gdb Befehle sind====
 
====Die nützlichsten gdb Befehle sind====
  
bt - Ausgabe eines stacktrace (siehe obrige Ausführung).
+
* '''bt''' - Ausgabe eines stacktrace (siehe obrige Ausführung).
 +
 
 +
*  '''up'''/'''down''' - Navigation innerhalb des strackframe
 +
 
 +
* '''thread [Nummer]''' - Anzeige des aktuellen Thread / Wechsel zu einem anderem Thread mit der angegebenen Nummer.
 +
 
 +
* '''c''' -  Fortsetzen der gestarteten Anwendung.
 +
 
 +
* '''print Ausdruck''' - den Wert des spezifizierten Ausdruckes ausgeben. Kann verwendet werden, den Wert bestimmter Variablen zum Beispiel zu kontrollieren, spezifizieren einfach den variablen Namen als Ausdruck
  
c - Fortsetzen der gestarteten Anwendung.
+
  (gdb) up
 +
#1  0xb7e05f6e in _int_free () from /lib/tls/libc.so.6
 +
(gdb) up
 +
#2  0xb7e04dcb in free () from /lib/tls/libc.so.6
 +
(gdb) up
 +
#3  0x081066b6 in ~cFrame (this=0x8f17110) at ringbuffer.c:352
 +
352      free(data);
 +
(gdb) print data
 +
$1 = (uchar *) 0x8f3a920 ""
  
print Ausdruck - den Wert des spezifizierten Ausdruckes ausgeben. Kann verwendet werden, den Wert bestimmter Variablen zum Beispiel zu kontrollieren, spezifizieren einfach den variablen Namen als Ausdruck
+
* '''quit''' - beendet gdb.
  
quit - beendet gdb.
+
====Laufende Prozesse debuggen====
  
Es ist auch möglich, gdb an einem bereits laufenden Prozeß anzudocken. Dieses kann mit „gdb Anwendung pid“ getan werden. gdb dockt am Prozeß an, der durch die Prozeßkennzeichnung spezifiziert wird, die könnte nützlich sein, wenn die Anwendung, in einer Endlos-Schleife verweilt und du feststellen möchtest, wo sie genau hängt.
+
Es ist auch möglich, gdb an einem bereits laufenden Prozeß anzudocken. Dieses kann mit '''gdb Anwendung pid''' getan werden. gdb dockt am Prozeß an, der durch die Prozeßkennzeichnung spezifiziert wird, die könnte nützlich sein, wenn die Anwendung, in einer Endlos-Schleife verweilt und du feststellen möchtest, wo sie genau hängt.

Version vom 22. Mai 2006, 18:45 Uhr

Der GNU Debugger, normalerweise GDB abgekürzt, ist der Standard-Debugger des GNU-Projekts. Als debuggen wird das Auffinden, Diagnostizieren und Eliminieren von Fehlern bezeichnet.

Ein Werkzeug zur Fehlerbereinigung von Software nennt sich Debugger. Der Debugger ermöglicht in der Regel eine Ablaufverfolgung des zu untersuchenden Programmes in einzelnen Schritten oder zwischen definierten Haltepunkten.

Inhaltsverzeichnis

Einführung

Dieses ist eine sehr kurze Einleitung in das Anwendung von gdb. Gerichtet ist an alle Anwender, der ein ernstes Problem mit dem VDR, einen Plugin oder einer anderen Anwendung hat. Und mit der Mithelfen möchte indem er Debugger-Ausgaben dem Entwickler oder dem Betreuer dieses Programmes, als ausführliche Informationen des Problemes übergibt.

Debugger Ausgaben

Programme können zusätzlich eingebaute Debugger Informationen enthalten. gdb kann die Debugger Informationen verwenden, um ausführlichere Informationen zur Verfügung zu stellen (wie Funktion Prototypen, Quellcode-Dateinamen und Zeilenzahlen,...), so ist es im Allgemeinen eine gute Idee, ein Programm so zu verwenden, des es eingebaute Debugger Informationen enthält.

Der Kompiler gcc hat eine Kommandozeilenschalter (-g), welcher den gcc anweist Debugger Informationen in die Objekt- und Ausführbaren Programmdateien zuschreiben.

Analysieren einer Segfault

Der Linux Kernel ist in der Lage, einen sogenannten Kernelspeicherabzug zu schreiben, wenn irgendeine Anwendung abstürzt. Dieser Kernelspeicherabzug notiert den Zustand des Prozesses zu der Zeit des Abbruchs. gdb kann solch einen Kernspeicherabzug lesen und Informationen aus ihm heraus erhalten.

Die meisten Distributionen haben diese Kernelspeicherabzug, die durch eine Einstellung gesperrt, so mußt sie zuerst reaktiviert werden. "ulimit -c unlimited" macht dies für die gegenwärtige Shell und alle Prozesse, die von ihm begonnen werden. Überprüfe die Bash-Man-Seite, wenn du mehr über den ulimit Befehl wissen möchtest.

# ulimit -c unlimited

Nächstes Mal wenn die Anwendung mit einem segfault abstürzt, siehst du, daß die Anzeige "Segmentation fault", in "Segmentation fault (core dumped)" geändert wurde. Und eine eine Datei "core" oder "core.pid" im aktuellen Verzeichnis gestellt wurde. Anmerkung: Du benötigst auch Schreibberechtigung für das aktuelle Verzeichnis, andernfalls wird keine Datei erstellt.

Jetzt ist es Zeit, gdb zu starten, um zu sehen, was genau geschah. Das erste Argument für gdb sollte die abgestürzte Anwendung, das zweite der Kernelspeicherabzug sein, der wegen des Abbruchs geschrieben wurde.

# gdb vdr /tmp/core.2841

gdb listet viele Informationen auf und begrüßt dich mit einer "(gdb)" Aufforderung, wenn es abgeschlossen ist. Die nützlichste Information für einen Entwickler ist ein sogenanntes Stacktrace.

Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
...
Core was generated by `/opt/vdr-1.4/bin/vdr -l 1 6 -v /video/vdr -L /opt/vdr-1.4/lib -s /opt/vdr-1.4/b'.
Program terminated with signal 11, Segmentation fault.
...
Reading symbols from /usr/lib/libstdc++.so.5...done.
Loaded symbols for /usr/lib/libstdc++.so.5
Reading symbols from /lib/tls/libm.so.6...Reading symbols from /usr/lib/debug/lib/tls/libm-2.3.2.so...done.
..
#0  0xb7e06090 in malloc_consolidate () from /lib/tls/libc.so.6
(gdb)

Schreibe "bt" in der Aufforderung um gdb aufzufordern, um einen Stacktrace zu auszugeben, welches du dann zum Entwickler verschicken kannst. Mit "quit" verlässt man gdb.

(gdb) bt
#0  0xb7e06090 in malloc_consolidate () from /lib/tls/libc.so.6
#1  0xb7e05f6e in _int_free () from /lib/tls/libc.so.6
#2  0xb7e04dcb in free () from /lib/tls/libc.so.6
#3  0x081066b6 in ~cFrame (this=0x8f17110) at ringbuffer.c:352
#4  0x08106bc2 in cRingBufferFrame::Delete (this=0x8f1b988, Frame=0x8f17110) at ringbuffer.c:411
#5  0x08106c4b in cRingBufferFrame::Drop (this=0x8f1b988, Frame=0x8f17110) at ringbuffer.c:421
#6  0x08106a15 in cRingBufferFrame::Clear (this=0x8f1b988) at ringbuffer.c:374
#7  0x08106958 in ~cRingBufferFrame (this=0x8f1b988) at ringbuffer.c:366
#8  0x080b1f0c in ~cDvbPlayer (this=0x8f179a0) at dvbplayer.c:276
#9  0x080b3e01 in cDvbPlayerControl::Stop (this=0x8f163a0) at dvbplayer.c:775
#10 0x080e0fc8 in cReplayControl::ProcessKey (this=0x8f163a0, Key=kBlue) at menu.c:4154
#11 0x081372a3 in main (argc=30, argv=0xbffffac4) at vdr.c:1022
(gdb) quit

Andere Weisen, gdb zu benutzen

Du kannst eine Anwendung unter Steuerung des gdb vollständig startem. Das tun gerechte Art gdb Anwendung. In der gdb Eingabeaufforderung verwendet run Parameter, um die Anwendung zu starten. Wenn die Anwendung ein Signal empfängt, wird gdb die Eingabeauforderung zeigen um Befehle dazu einzugeben. Du kannst jederzeit Strg-C drücken, um eine gdb Eingabeauforderung zu erhalten.

Die nützlichsten gdb Befehle sind

  • bt - Ausgabe eines stacktrace (siehe obrige Ausführung).
  • up/down - Navigation innerhalb des strackframe
  • thread [Nummer] - Anzeige des aktuellen Thread / Wechsel zu einem anderem Thread mit der angegebenen Nummer.
  • c - Fortsetzen der gestarteten Anwendung.
  • print Ausdruck - den Wert des spezifizierten Ausdruckes ausgeben. Kann verwendet werden, den Wert bestimmter Variablen zum Beispiel zu kontrollieren, spezifizieren einfach den variablen Namen als Ausdruck
(gdb) up
#1  0xb7e05f6e in _int_free () from /lib/tls/libc.so.6
(gdb) up
#2  0xb7e04dcb in free () from /lib/tls/libc.so.6
(gdb) up
#3  0x081066b6 in ~cFrame (this=0x8f17110) at ringbuffer.c:352
352       free(data);
(gdb) print data
$1 = (uchar *) 0x8f3a920 ""
  • quit - beendet gdb.

Laufende Prozesse debuggen

Es ist auch möglich, gdb an einem bereits laufenden Prozeß anzudocken. Dieses kann mit gdb Anwendung pid getan werden. gdb dockt am Prozeß an, der durch die Prozeßkennzeichnung spezifiziert wird, die könnte nützlich sein, wenn die Anwendung, in einer Endlos-Schleife verweilt und du feststellen möchtest, wo sie genau hängt.