在制作期间,我发现了一个错误:
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];
...
该函数将一些内容打印到缓冲区中。
任何人都知道这种错误通常意味着什么?
答案 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
需要复杂的启发式算法。另见: