2010-03-15 1 views
25

Während einer Marke, ich sehe einen Fehler entlang der Linien von:Was bedeutet dieser Fehler: `somefile.c: 200: Fehler: Die Rahmengröße von 1032 Bytes ist größer als 1024 Bytes '?

cc1: warnings being treated as errors 
somefile.c:200: error: the frame size of 1032 bytes is larger than 1024 bytes 

Die Zeilennummer zeigt auf der schließenden Klammer der ac-Funktion, die eine Signatur wie folgt hat:

void trace(SomeEnum1 p1, SomeEnum2 p2, char* format, ...) { 
    char strBuffer[1024]; 
    ... 

Die Funktion druckt einige Sachen in den Puffer.

Wer weiß, was diese Art von Fehler im Allgemeinen bedeutet?

+1

Was ist in der Funktion? – GManNickG

+0

Was ist über der Funktion? – niry

+0

@GMan aktualisiert Code-Snippet. @niry eine andere Funktion. –

Antwort

32

Ich vermute, es gibt einige große Puffer in dieser Routine, die Stapel zugeordnet ist; Dies führt wahrscheinlich dazu, dass der Stack-Frame dieser Funktion 1024 Bytes überschreitet, was anscheinend ein Compiler-erzwungener Grenzwert für die Architektur ist, auf der Sie aufbauen. Zu möglichen Lösungen gehören das Übergeben eines Compiler-Flags, um die Warnung zu lockern, das Erweitern der Obergrenze der Stapelgröße oder das dynamische Zuweisen des Puffers. Hier

+2

Tatsächlich ist das erste, was passiert, eine Zuweisung eines Puffers der Größe 1024. –

+2

Mann Ich wollte das auch sagen, aber ich wollte um die Funktion zuerst zu sehen. :) – GManNickG

+0

Ich habe Ihre Kommentare für gute Absichten upvottiert :) –

13

ist die GCC-Dokumentation auf diese Warnung bezieht:

STACK_CHECK_MAX_FRAME_SIZE

Die maximale Größe eines Stapelrahmens, in Bytes. GNU CC wird Prüfanweisungen in Nicht-Blatt-Funktionen generieren, um sicherzustellen, dass mindestens diese vielen Bytes des Stapels verfügbar sind. Wenn ein Stapelrahmen größer als diese Größe ist, ist die Stapelprüfung nicht zuverlässig und GNU CC gibt eine Warnung aus. Der Standardwert ist so gewählt, dass GNU CC auf den meisten Systemen nur einen Befehl generiert. Normalerweise sollten Sie den Standardwert dieses Makros nicht ändern.

Von http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_17.html#SEC214

+2

Der Stapelrahmen ist, wo der Compiler Auto-Variablen platziert. Wenn Sie andere lokale Variablen als strBuffer haben, werden Sie das Limit von 1024 überschreiten. Versuchen Sie, die Größe von strBuffer zu reduzieren, um Platz für zusätzliche lokale Variablen zu schaffen. Der Compiler kann auch etwas Platz in dem Stapelrahmen für seine eigene Verwendung verwenden, wobei er typischerweise die Rückkehradresse und Hardware-Register speichert. –

+0

Sie können auch versuchen, strBuffer vom Stapel in einen anderen Speicherbereich wie den Heap oder den globalen Speicher zu verschieben. Um es auf den Heap zu verschieben, müssten Sie malloc und free verwenden und Sie würden einen Leistungseinbruch erleiden. Wenn Sie ihn in den globalen Bereich verschieben, müssen Sie nur das statische Qualifikationsmerkmal hinzufügen, aber Sie verlieren etwas globalen Speicherplatz. Ich mache alle möglichen Annahmen über Ihre Hardware und Ihren Compiler. –

3

-Wframe-larger-than

Die Warnung wird durch -Wframe-larger-than erzeugt. man gcc von GCC 7 sagt:

Warn if the size of a function frame is larger than len bytes. The computation done to determine the stack frame size is approximate and not conservative. The actual requirements may be somewhat greater than len even if you do not get a warning. In addition, any space allocated via "alloca", variable-length arrays, or related constructs is not included by the compiler when determining whether or not to issue a warning.

Minimal Beispiel

int main(void) { 
    char s[1024]; 
    return 0; 
} 

und:

$ gcc -std=c99 -O0 -Wframe-larger-than=1 a.c 
a.c: In function ‘main’: 
a.c:4:1: warning: the frame size of 1040 bytes is larger than 1 bytes [-Wframe-larger-than=] 
} 
^ 
$ gcc -std=c99 -O0 -Wframe-larger-than=2048 a.c 
# No warning. 

Warum diese

Betriebssysteme existiert muss t begrenzen er stapelt die Größe, sonst würde es wachsen, bis es den Heap erreicht/mmap s und alles würde unvorhersehbar brechen.

Linux sendet ein Signal, wenn das Programm versucht, über die maximale Stapelgröße hinaus zu wachsen.

-Wframe-larger-than= ist eine Möglichkeit, um das Überlaufen des Stacks zu verhindern, indem die lokalen Variablen der Funktion (die auf dem Stack platziert sind) klein gehalten werden.

Es gibt jedoch keine Kompilierzeit-Garantie, da das Problem wahrscheinlich auftritt, wenn rekursive Funktionen aufgerufen werden, und es kommt darauf an, wie oft es rekursiv ist.

Die Lösung besteht darin, Speicher mit malloc zu reservieren, anstatt große Arrays als lokale Variablen zu verwenden. Dies endet mit mmap Speicher. Der Hauptunterschied zwischen dem Stack und dem malloc Speicher ist, dass der Stack zusammenhängend sein muss, was einfach zu einer großen Speicherpackeffizienz führt, während malloc komplexe Heuristiken erfordert. Siehe auch: