这个错误是什么意思:`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 

行号指向ac函数的右括号,其具有如下签名:

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

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

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

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

以下是参考此警告的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

-Wframe-larger-than

警告由-Wframe-larger-than生成。 海湾合作委员会第7号人员说:

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

最小的例子

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

和:

 $ gcc -std=c99 -O0 -Wframe-larger-than=1 ac ac: In function 'main': ac: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 ac # No warning. 

为什么会这样

操作系统必须限制堆栈大小,否则它会增长直到它到达堆/ mmap并且一切都会无法预测地破坏。

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

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

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

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

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