这个错误是什么意思:`somefile.c:200:错误:1032字节的帧大小大于1024字节`?

时间:2010-03-15 22:14:14

标签: c gcc build makefile compiler-errors

在制作期间,我发现了一个错误:

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];
    ...

该函数将一些内容打印到缓冲区中。

任何人都知道这种错误通常意味着什么?

3 个答案:

答案 0 :(得分:34)

我猜这个例程中有一些大的缓冲区是堆栈分配的;这可能导致该函数的堆栈帧超过1024个字节,这似乎是您正在构建的体系结构的一些编译器强制限制。可能的解决方案包括传递编译器标志以放松警告,扩展堆栈大小的上限或动态分配缓冲区。

答案 1 :(得分: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 :(得分:6)

<强> -Wframe-larger-than

警告由-Wframe-larger-than生成。 GCC 7的man gcc说:

  

如果函数帧的大小大于len个字节,则发出警告。用于确定堆栈帧大小的计算是近似的而不是保守的。该      即使您没有收到警告,实际要求也可能略高于len。此外,通过&#34; alloca&#34;,可变长度数组分配的任何空间,      在确定是否发出警告时,编译器不包括或相关结构。

最小例子

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并且一切都会无法预测地破坏。

如果程序试图超出最大堆栈大小,Linux会发送一个信号。

-Wframe-larger-than=是一种通过保持函数局部变量(放置在堆栈上)较小来帮助防止堆栈溢出的方法。

然而,没有编译时保证,因为在调用递归函数时可能会发生问题,而这一切都归结为它的递归次数。

解决方案是使用malloc分配内存,而不是使用大型数组作为局部变量。最终使用mmap内存。

堆栈和malloc内存之间的关键区别在于堆栈必须是连续的,这很简单可以提高内存打包效率,而malloc需要复杂的启发式算法。另见: