PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : GCC Arrayüberlauf


rotalever
2007-02-11, 19:09:40
Die Frage steckt schon im Titel, kann man mit dem GCC-Compiler feststellen, ob beim Array-zugriff ein außerhalb liegendes Element angewählt wird? MSVC++ kann das. Ich wills aber auch unter Linux!
Falls wer nicht versteht, was ich meine (In den Zeilen wo Fehler steht, soll das Programm zumindest im Debug-Modus abbrechen, der Debugger z.B. GDB soll sagen "in Zeile xyz ist arrayüberlauf blablabal"):

void main() {
int *myarray,b;
b = 4;
myarray = (int *) malloc(b*sizeof(int));
myarray[2] = 3;
myarray[-1] = 5; // FEHLER
myarray[7] = 1; // FEHLER
}

Simon
2007-02-11, 19:21:48
Wo ist jetzt dein Problem?
gdb ./programm
run
where

:confused:

Für GUI kannst du z.B. ddd nehmen.

class Foo: pass
2007-02-11, 19:26:30
Die Frage steckt schon im Titel, kann man mit dem GCC-Compiler feststellen, ob beim Array-zugriff ein außerhalb liegendes Element angewählt wird? MSVC++ kann das. Ich wills aber auch unter Linux!
Falls wer nicht versteht, was ich meine (In den Zeilen wo Fehler steht, soll das Programm zumindest im Debug-Modus abbrechen, der Debugger z.B. GDB soll sagen "in Zeile xyz ist arrayüberlauf blablabal"):


AFAIK kanns der gcc nicht.
Ich empfehle valgrind zum Testen von overruns, underruns, leaks, etc.

lg,
Stefan

rotalever
2007-02-11, 19:26:50
Zeigt der dann Array-Überlauf an?

class Foo: pass
2007-02-11, 19:31:01
Zeigt der dann Array-Überlauf an?
Ja.
http://valgrind.org/

Edit:
Leider kann valgrind allerdings nur overruns / underruns bei heap memory checken, d.h. wenn du ein array am stack allokierst und dann ungültig indizierst checkt er den Fehler nicht (geht auch net so einfach).
http://valgrind.org/downloads/variants.html?njn
valgrind-annelid scheint sehr brauchbar zu sein.

lg,
Stefan

rotalever
2007-02-11, 20:12:32
Valgrind scheint ein gutes Tool für sowas zu sein, mit dem GCC und GDB alleine gehts wohl dann nicht, wenn ich es richtig verstehe?

edit: Naja, wobei wenn ich mir das genauer durchlese, so viel kann das nun auch wieder nicht. Gibts nicht vll. noch was besseres?

Coda
2007-02-11, 20:21:06
Valgrind ist bereits das beste. Ich würde sonst was dafür geben, das auch unter Windows zu haben.

transstilben
2007-02-11, 20:28:05
Schon mal drüber nachgedacht, die Arraygrenzen selbst zu prüfen ?

z.B.

assert ((Index >= 0) && (Index <= MAXINDEX));

Spricht was dagegen ?

Coda
2007-02-11, 20:50:23
Ist halt aufwändig das überall reinzubauen und vor allem es wieder rauszubauen wenn's dann läuft.

ScottManDeath
2007-02-11, 20:58:37
Asserts werden doch im release builde raus #defined

transstilben
2007-02-11, 21:09:31
Asserts werden doch im release builde raus #defined

Genau so ist es (s. include "assert.h").
Allerdings sollte man sich davon besser nochmal selbst überzeugen, denn sobald das assert im Release-Fall noch "was kostet" ist es natürlich mit Vorsicht zu genießen.
Hab schon erlebt, das im RELEASE-Build von jedem assert noch ein "RET" zurückgeblieben ist. Ich weiß aber nicht mehr genau ob das bei GCC oder MS Visual C++ 6.0 war.

rotalever
2007-02-11, 21:47:25
Ok, wenn Valgrind scheinbar doch das beste ist, bin ich ja beruhigt^^.

Werds bald mal ausprobieren, ansonsten kann debuggen halt extrem nervig sein, da gibts zum teil fehler die glaubt man nich...

transstilben
2007-02-11, 22:39:59
Ok, wenn Valgrind scheinbar doch das beste ist, bin ich ja beruhigt^^.

Werds bald mal ausprobieren, ansonsten kann debuggen halt extrem nervig sein, da gibts zum teil fehler die glaubt man nich...

Ich persönlich halte es für das Beste, Programme möglichst so zu schreiben, daß keine Verletzungen von Arraygrenzen stattfinden können ... ;)

Coda
2007-02-11, 23:02:41
Jeder Mensch macht mal Fehler, daher ist das zwar ein guter Rat, aber nicht immer erreichbar.

ScottManDeath
2007-02-11, 23:46:46
Ich hab mein eigenes Assert Makro, welches im Release Build zu einem {} Block #defined wird. Bei dem Standard Assert Makro wird es zu eine (void*)0.

Summa summarum: Asserts, better safe than sorry.

Compiler sind gar nicht so dumm, VC8 hat zum Beispiel fuer mein 2100 case switch statement binary search gemacht, dh. 12 conditional jumps im worst case =)

No.3
2007-02-11, 23:55:44
Jeder Mensch macht mal Fehler, daher ist das zwar ein guter Rat, aber nicht immer erreichbar.

bei jedem Array Zugriff die Grenzen abzufragen beschleunigt den Zugriff gar immens...

Xmas
2007-02-12, 00:00:27
Compiler sind gar nicht so dumm, VC8 hat zum Beispiel fuer mein 2100 case switch statement binary search gemacht, dh. 12 conditional jumps im worst case =)
Da erscheint mir eine Sprung(hash)tabelle allerdings sinnvoller.

bei jedem Array Zugriff die Grenzen abzufragen beschleunigt den Zugriff gar immens...
Wieso sollte das der Fall sein?

Coda
2007-02-12, 00:16:26
bei jedem Array Zugriff die Grenzen abzufragen beschleunigt den Zugriff gar immens...
Must ja nicht ins Release einbauen. Ach btw. Vista ist komplett mit Array- und Stack-Guards durchkompiliert ;)

transstilben
2007-02-12, 00:17:19
Ich hab mein eigenes Assert Makro, welches im Release Build zu einem {} Block #defined wird. Bei dem Standard Assert Makro wird es zu eine (void*)0.

Heißt das, ein { } Block ist besser als ein (void*)0 weil der Compiler daraus was anderes macht (nämlich nichts) ?

Falls dem nicht so ist, wäre es ja auch denkbar, in einem speziellen "Präprozessorlauf" die "assert"-Zeilen im Rahmen des Release-Builds "mit Gewalt" zu entfernen.

ScottManDeath
2007-02-12, 00:27:46
Da erscheint mir eine Sprung(hash)tabelle allerdings sinnvoller.


Mhmm, die Werte sind aufsteigend sortiert und haben 32 bit range, wobei die Mehrzahl in 16 bit reinpassen. Inwiefern wuerde da ein jump table helfen?

Performance ist mir nicht wichtig, ist eh nur fuer Debuggen (aus Zahlen den OpenGL enum string machen).

transstilben
2007-02-12, 00:39:12
Mhmm, die Werte sind aufsteigend sortiert und haben 32 bit range, wobei die Mehrzahl in 16 bit reinpassen. Inwiefern wuerde da ein jump table helfen?

Mit einer geeigneten Hash-Funktion wäre es halt evtl. performanter. Tja, so schlau ist dann der Compiler anscheinend doch nicht.:biggrin:

ethrandil
2007-02-12, 11:37:14
Mhmm, die Werte sind aufsteigend sortiert und haben 32 bit range, wobei die Mehrzahl in 16 bit reinpassen. Inwiefern wuerde da ein jump table helfen?

Performance ist mir nicht wichtig, ist eh nur fuer Debuggen (aus Zahlen den OpenGL enum string machen).
Erwartete Laufzeit O(1) ? Wenn mans geschickt macht kommt man mit etwas mehr Speicherplatz auch im WorstCase auf unter 12 Jumps, dafür ein paar mehr Berechnungen (modulo).

mfg
- eth

ScottManDeath
2007-02-12, 18:51:31
Gut, OK. Stymmt. Sowas ist dann glaube ich auch zuviel verlangt von einem Compiler den ungewoehnlichen Fall von pervers vielen cases zu optimieren. =) Ich war jedenfalls positiv ueberrascht.

No.3
2007-02-12, 19:01:50
Wieso sollte das der Fall sein?

weils ironisch gemeint war ;)