2010-03-15 12 views
25

Durante un hacer, estoy viendo un error en la línea de:¿Qué significa este error: `somefile.c: 200: error: el tamaño del marco de 1032 bytes es mayor que 1024 bytes`?

cc1: warnings being treated as errors 
somefile.c:200: error: the frame size of 1032 bytes is larger than 1024 bytes 

número de puntos de la línea para la llave de cierre de la función de corriente alterna que tiene una firma así:

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

El función imprime algunas cosas en el búfer.

¿Alguien sabe qué significa este tipo de error en general?

+1

Qué hay en la función? – GManNickG

+0

¿Qué hay arriba de la función? – niry

+0

@GMan fragmento de código actualizado. @niry otra función. –

Respuesta

32

Supongo que hay un gran búfer en esa rutina asignada por la pila; es probable que esto provoque que el marco de la pila de esa función exceda los 1024 bytes, lo que parece ser un límite impuesto por el compilador para la arquitectura sobre la que está construyendo. Las posibles soluciones incluirían pasar un indicador de compilación para relajar la advertencia, expandir el límite superior del tamaño de la pila o asignar dinámicamente el almacenamiento intermedio.

+2

De hecho, lo primero que sucede es una asignación de un buffer de tamaño 1024. –

+2

Hombre, iba a decir esto también, pero quería para ver la función primero :) – GManNickG

+0

He actualizado sus comentarios con buenas intenciones :) –

13

Aquí está la documentación de GCC en referencia 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 que no son de hoja para garantizar que al menos estén disponibles muchos bytes de pila. Si un marco de pila es más grande que este tamaño, la verificación de 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 debería cambiar el valor predeterminado de esta macro.

De http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_17.html#SEC214

+2

El marco de la pila es donde el compilador coloca las variables automáticas. Si tiene otras variables locales distintas de strBuffer, va a desbordar el límite de 1024. Intenta reducir el tamaño de strBuffer para dejar espacio para variables locales adicionales. El compilador también puede usar algo de espacio en el marco de la pila para su propio uso, generalmente guardando la dirección de retorno y los registros de hardware. –

+0

También puede intentar mover strBuffer de la pila a otra área de memoria como el montón o la memoria global. Moverlo al montón requeriría usar malloc y libre y obtendrías un golpe de rendimiento. Si bien moverlo al espacio global solo requeriría agregar el calificador "estático", pero perdería un poco de espacio global. Estoy haciendo todo tipo de suposiciones sobre su hardware y compilador. –

3

-Wframe-larger-than

La advertencia es generada por -Wframe-larger-than. man gcc de GCC 7 dice:

Warn if the size of a function frame is larger than len bytes. The computation done to determine the stack frame size is approximate and not conservative. The actual requirements may be somewhat greater than len even if you do not get a warning. In addition, any space allocated via "alloca", variable-length arrays, or related constructs is not included by the compiler when determining whether or not to issue a warning.

ejemplo Mínimo

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 qué existe este

sistemas operativos deben limitar t El tamaño de la pila, de lo contrario, crecerá hasta que llegue al montón/mmap y todo se romperá de manera 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 las variables locales de función (que se colocan en la pila) pequeñas.

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 en lugar de utilizar grandes matrices 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 eficacia de embalaje de memoria, mientras que malloc requiere una heurística compleja. Ver también:

Cuestiones relacionadas