Pie*_*tte 27 c gcc compiler-errors makefile build
在制作过程中,我发现了一个错误:
cc1: warnings being treated as errors
somefile.c:200: error: the frame size of 1032 bytes is larger than 1024 bytes
Run Code Online (Sandbox Code Playgroud)
行号指向ac函数的右括号,其具有如下签名:
void trace(SomeEnum1 p1, SomeEnum2 p2, char* format, ...) {
char strBuffer[1024];
...
Run Code Online (Sandbox Code Playgroud)
该函数将一些内容打印到缓冲区中.
任何人都知道这种错误通常意味着什么?
fbr*_*eto 35
我猜这个例程中有一些大的缓冲区是堆栈分配的; 这可能导致该函数的堆栈帧超过1024个字节,这似乎是您正在构建的体系结构的一些编译器强制限制.可能的解决方案包括传递编译器标志以放松警告,扩展堆栈大小的上限或动态分配缓冲区.
Pie*_*tte 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
-Wframe-larger-than
警告由生成-Wframe-larger-than.man gccGCC 7的说法是:
如果函数帧的大小大于len个字节,则发出警告.用于确定堆栈帧大小的计算是近似的而不是保守的.即使您没有收到警告,实际要求也可能略高于len.此外,在确定是否发出警告时,编译器不包括通过"alloca",可变长度数组或相关构造分配的任何空间.
最小的例子
int main(void) {
char s[1024];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
和:
$ gcc -std=c99 -O0 -Wframe-larger-than=1 main.c
main.c: In function ‘main’:
main.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 main.c
# No warning.
Run Code Online (Sandbox Code Playgroud)
为什么会这样
操作系统必须限制堆栈大小,否则它会一直增长直到达到堆/ mmaps并且一切都会无法预测地破坏.
如果程序试图超出最大堆栈大小,Linux会发送信号.
-Wframe-larger-than= 是一种通过保持函数局部变量(放置在堆栈上)较小来帮助防止堆栈溢出的方法.
然而,没有编译时保证,因为在调用递归函数时可能会发生问题,而这一切都归结为它的递归次数.
解决方案是分配内存malloc而不是使用大型数组作为局部变量.这最终使用mmap内存.
堆栈和malloc内存之间的关键区别在于堆栈必须是连续的,这很简单,可以提高内存打包效率,同时malloc需要复杂的启发式算法.也可以看看:
| 归档时间: |
|
| 查看次数: |
30099 次 |
| 最近记录: |