PC-Pools des INS und IAM

Wie finde ich "Segementation faults"?

Eine kurze Einführung in gdb

Jeder, der ein wenig C/C++ programmiert hat, kennt den folgenden Fehler:

$ ./seg
Segmentation fault

Dieser wurde mit dem beiliegenden C Programm "seg" erzeugt. Dies soll im Folgenden unser Beispiel sein. Dieses Beispiel kann mit

$ gcc -o seg seg.c

übersetzt werden. Die Suche nach solchen Fehlern kann sehr langwierig und kompliziert sein, wenn man nicht die richtigen Hilfsmittel zu Verfügung hat. Das Mittel der Wahl ist hier ein sogennanter Debuger. Das ist ein Programm, dass es ermöglicht in einen Blick in ein laufendes Programm zu werfen und den Programmablauf nachzuvollziehen. Der Debuger unserer Wahl wird "gdb" sein. Um dem Debuger einen Blick ins innere eines Programms zu ermöglichen, muss zunächst das Programm mit sogennanten "Debugflags" versehen werden. Dies ermöglicht es später einem Stück Binärcode eine Programmzeile zuzuordnen. Dies kann der Compiler "gcc" während des Übersetzens des Programms erledigen. Dazu ruft man ihn mit der Option "-g" auf. Also lautet die Zeile, um das Programm mit "Debugflags" zu compilieren

$ gcc -g -o seg seg.c

Nun startet man den Debuger in dem man in der Shell

$ gdb seg

eingibt. Der Debuger öffnet sich. Wenn man nun den Befehl "run" eingibt, wird das Programm gestartet und man erhält folgende Ausgabe:

(gdb) run
Starting program:~/howto_cip/seg
Program received signal SIGSEGV, Segmentation fault.
0x0804840a in gen_segfault (n=5, ar=0x804a008) at seg.c:9
9 ar[i][j] = i*j;

Die drei letzen Zeilen sagen aus, dass das Programm mit einem "Segmentation fault" beendet wurde. Der Debuger konnte sogar ermitteln wo der Fehler auftrat und gibt die Quelldatei und die Zeile aus. Diese einzelne Zeile scheint zunächst wenig verdächtig. Da es sich um einen Arrayzugriff handelt, wäre es interressant, den Wert der Laufvariablen i und j zu ermitteln. Dies kann mit den Befehl

(gdb) print j
$1 = 0
(gdb) print i
$1 = 5

erreicht werden. Wenn wir nun die zugehörigen Schleifen:

for( i = 0; i <= n; ++i )
for( j = 0; j <= n ; ++j )
ar[i][j] = i*j;

betrachten, ist der Fehler schnell identifiziert. Da wir nur eine 5x5 Matrix übergeben haben, dürfen wir natrlich nicht bis zum Index 5 auf die Matrix zugreifen. Daher ist es korrekt, wenn wir stattdessen schreibe

for( i = 0; i < n; ++i )
for( j = 0; j < n ; ++j )
ar[i][j] = i*j;

Abschliessend sei noch bemerkt, dass "gdb" einen größeren Befehlsumfang hat. Mit dem Befehl "help" kann man sich diese leicht selbst erschliessen.

 

 

Contact

Managing Director: Prof. Dr. Anton Bovier
Chief Administrator: Dr. B. Pfistner
geschaeftsfuehrung@iam.uni-bonn.de
Imprint

Mailing adresses

Institute for Applied Mathematics
University of Bonn
Endenicher Allee 60
D-53115 Bonn / Germany

 

Phone:(+) 49-228-73-4875
Fax: (+) 49-228-73-6716