2010-03-15 102 views
25

在一次化妝,我看到的線沿線的一個錯誤:這個錯誤的含義是什麼:`somefile.c:200:錯誤:1032字節的幀大小大於1024字節?

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

行號指向c函數的右括號有這樣的簽名:

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

的函數將一些東西打印到緩衝區中。

任何人都知道這種類型的錯誤一般意味着什麼?

+1

了哪些功能? – GManNickG 2010-03-15 22:16:58

+0

功能上面是什麼? – niry 2010-03-15 22:21:44

+0

@GMan更新了代碼片段。 @niry另一個功能。 – 2010-03-15 22:35:28

回答

32

我猜這個例程中有一些大的緩衝區是堆棧分配的;這可能會導致該函數的堆棧幀超過1024個字節,這似乎是您正在構建的體系結構的一些編譯器強制限制。可能的解決方案將包括傳遞一個編譯器標誌來放寬警告,擴展堆棧大小的上限或動態分配緩衝區。

+2

事實上,第一件事是發生1024位緩衝區的分配。 – 2010-03-15 22:34:08

+2

我也會這麼說,但我想要先看功能。 :) – GManNickG 2010-03-15 22:36:03

+0

我已經upvoted您的意見好意:) – 2010-03-15 22:38:41

13

這裏是GCC文檔參照此警告:

STACK_CHECK_MAX_FRAME_SIZE

一個堆棧幀的最大大小,以字節爲單位。 GNU CC將在非葉函數中生成探測指令,以確保至少有很多字節的堆棧可用。如果堆棧幀大於此大小,堆棧檢查將不可靠,並且GNU CC將發出警告。選擇默認值以便GNU CC僅在大多數系統上生成一條指令。您通常不應該更改此宏的默認值。

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

+2

堆棧幀是編譯器放置自動變量的地方。如果你有任何其他局部變量,那麼strBuffer你會溢出1024的限制。嘗試減小strBuffer的大小,爲額外的局部變量騰出空間。編譯器也可以在堆棧幀中使用一些空間供自己使用,通常會保存返回地址和硬件寄存器。 – 2010-03-17 05:20:38

+0

您也可以嘗試將strBuffer從堆棧移動到其他內存區域,如堆或全局內存。將它移到堆中需要使用malloc和free,並且你會獲得一個性能優勢。將它移動到全局空間只需要添加'靜態'限定符,但是你會放棄一些全局空間。我正在對你的硬件和編譯器做出各種假設。 – 2010-03-17 05:47:18

3

-Wframe-larger-than

-Wframe-larger-than生成警告。 GCC 7 man gcc說:

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.

小例子

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

和:

$ 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. 

爲什麼這存在

操作系統必須限制ŧ他堆棧大小,否則它會增長,直到它到達堆/ mmap s,一切都將無法預料地打破。

如果程序試圖增長超過最大堆棧大小,Linux會發送一個信號。

-Wframe-larger-than=通過保持函數局部變量(放置在堆棧上)很小,有助於防止堆棧溢出。

但是沒有編譯時間保證,因爲在調用遞歸函數時可能會發生問題,而這一切都歸結爲它遞歸的次數。

解決方法是用malloc分配內存,而不是使用大型數組作爲局部變量。這最終使用mmap內存。

堆棧和malloc內存的關鍵區別在於堆棧必須是連續的,這很簡單會導致很大的內存包裝效率,而malloc需要複雜的啓發式。另請參見:

相關問題