Milan Stephan
Fotografie & IT

Zurück zur SP1 Übersicht

gdb_example.c

#include <stdio.h>

static void initArray(long *array, size_t size) {
	for (size_t i = 0; i <= size; i++) {
		array[i] = 0;
	}
}

int main(void) {

	long *array;
	long buf[7];
	array = buf;

	initArray(buf, sizeof(buf)/sizeof(long));

	while (array != buf+sizeof(buf)/sizeof(long)) {
		printf("p=%p\n", (void*) array);
		printf("%ld\n", *array);
		array++;
	}
}

/*
Debugging des Programms mit cgdb
(cgdb markiert die Zeile VOR ihrer Ausführung.)
cgdb ./gdb_example
> b main        // Breakpoint auf main setzen
> run           // Ausführen, bis Breakpoint erreicht ist
> display array // Ziel des Pointers "array" nach jedem Schritt ausgeben
> (gibt 0x0 aus - array ist noch nicht initialisiert.)
> n             // Nächste Instruktion ausführen (in dem Fall die Zuweisung array = buf)
> (gibt einen Pointer auf buf aus)
> n             // Nächste Intruktion (initArray)
> (gibt 0x0 aus)
Hier ist der Fehler schon passiert (in der Funktion initArray).

> b initArray
> run (bestätigen, dass aktueller Durchlauf unterbrochen wird)
Wir landen beim ersten Breakpoint - der main().
> c             // Zum zweiten Breakpoint (initArray)
> display i
(Noch nicht initialisiert, daher "zufälliger" Wert.)
> n             // Nächste Instruktion
> (Enter)       // Mehrmals drücken, um die vorherige Aktion zu wiederholen und ein paar Instruktionen auszuführen.
Der aktuelle Index, in den geschrieben wird, wird angezeigt.

Der höchste Index, auf den geschrieben wird, ist 7.
Da das Array eine Größe von 7 Elementen hat, ist der größte erlaubte Index 6.

Warum zeigt der Zeiger "array" nach dem Aufruf von initArray auf 0x0 (NULL)?

Erklärung:
Der Funktion wird ein Zeiger auf das Array im Stackframe der main() übergeben.
Beim Durchlaufen des Arrays wird die Schleife eine Iteration zu häufig aufgerufen.

Stackaufbau in der main():
0xfffff...
[...]
long *array <
long buf[6] <
long buf[5] <
long buf[4] <
long buf[3] <
long buf[2] <
long buf[1] <
long buf[0] <---- Pointer, der an initArray übergeben wird
[...]
0x0

Alle mit "<" markierten Einträge auf dem Stack werden durch initArray überschrieben.
Durch das Schreiben von buf[7] wird effektiv der Zeiger "array", der direkt nach buf auf dem Stack liegt, überschrieben und auf 0x0 (=NULL) gesetzt.

Lösung:
initArray reparieren, indem in der Schleifenbedingung das "<=" durch "<" ersetzt wird.
Damit wird die Schleife eine Iteration weniger oft durchlaufen und "array" wird nicht überschrieben.

Weiteres:
Variable setzen:
> set var i = 12345

*/