trek - ¿Qué significa este error: `somefile.c: 200: error: el tamaño del marco de 1032 bytes es mayor que 1024 bytes`?
talla de bicicleta para 1 70 (3)
Durante una marca, estoy viendo un error en la línea de:
cc1: warnings being treated as errors
somefile.c:200: error: the frame size of 1032 bytes is larger than 1024 bytes
El número de línea apunta al corchete de cierre de la función ac que tiene una firma como esta:
void trace(SomeEnum1 p1, SomeEnum2 p2, char* format, ...) {
char strBuffer[1024];
...
La función imprime algunas cosas en el búfer.
¿Alguien sabe qué significa este tipo de error en general?
Aquí está la documentación de GCC que se refiere a esta advertencia:
STACK_CHECK_MAX_FRAME_SIZE
El tamaño máximo de un marco de pila, en bytes. GNU CC generará instrucciones de sondeo en funciones no de hoja para garantizar que al menos esta cantidad de bytes de pila estén disponibles. Si un marco de pila es más grande que este tamaño, la verificación de la pila no será confiable y GNU CC emitirá una advertencia. El valor predeterminado se elige para que GNU CC solo genere una instrucción en la mayoría de los sistemas. Normalmente, no debe cambiar el valor predeterminado de esta macro.
De http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_17.html#SEC214
Supongo que hay una gran cantidad de búfer en esa rutina que está asignada a la pila; es probable que esto haga que el marco de pila de esa función supere los 1024 bytes, que parece ser un límite impuesto por el compilador para la arquitectura sobre la que se está construyendo. Las posibles soluciones incluirían pasar un indicador de compilador para relajar la advertencia, expandir el límite superior del tamaño de la pila o asignar dinámicamente el búfer.
-Wframe-larger-than
La advertencia es generada por -Wframe-larger-than
. man gcc
de GCC 7 dice:
Avisar si el tamaño de un marco de función es mayor que len bytes. El cálculo realizado para determinar el tamaño del marco de pila es aproximado y no conservativo. Los requisitos reales pueden ser algo mayores que len incluso si no recibe una advertencia. Además, el compilador no incluye ningún espacio asignado mediante "alloca", matrices de longitud variable o construcciones relacionadas al determinar si se debe emitir una advertencia o no.
Ejemplo minimo
int main(void) {
char s[1024];
return 0;
}
y:
$ 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.
Por que esto existe
Los sistemas operativos deben limitar el tamaño de la pila, de lo contrario crecería hasta alcanzar el montón / mmap
y todo se rompería de forma impredecible.
Linux envía una señal si el programa intenta crecer más allá de ese tamaño máximo de pila.
-Wframe-larger-than=
es una forma de ayudar a evitar que la pila se desborde, manteniendo pequeñas las variables locales de la función (que se colocan en la pila).
Sin embargo, no hay garantía de tiempo de compilación, ya que es probable que el problema ocurra al llamar a funciones recursivas, y todo se reduce a la cantidad de veces que se repite.
La solución es asignar memoria con malloc
lugar de utilizar matrices grandes como variables locales. Esto termina usando la memoria mmap
.
La diferencia clave entre la pila y la memoria malloc
es que la pila debe ser contigua, lo que es simple conduce a una gran eficiencia de empaquetamiento de la memoria, mientras que malloc
requiere complejas heurísticas. Ver también: