uso una que proceso pilas niquel las desecho descarga correcto comunes carga cadmio baterias bateria automovil automotriz c compiler-construction callstack

una - uso de las pilas comunes



ComprobaciĆ³n del uso de la pila en tiempo de compilaciĆ³n (7)

¿Hay alguna forma de conocer y generar el tamaño de pila necesario para una función en tiempo de compilación en C? Esto es lo que me gustaría saber:

Tomemos alguna función:

void foo(int a) { char c[5]; char * s; //do something return; }

Al compilar esta función, me gustaría saber cuánto espacio de pila consumirá cuando se llame. Esto podría ser útil para detectar la declaración en la pila de una estructura que oculta un gran buffer.

Estoy buscando algo que imprima algo como esto:

archivo foo.c: función uso de pila foo es n bytes

¿Hay alguna manera de no mirar el conjunto generado para saber eso? ¿O un límite que se puede establecer para el compilador?

Actualización: no estoy tratando de evitar el desbordamiento de la pila en tiempo de ejecución para un proceso dado, estoy buscando una forma de encontrar antes del tiempo de ejecución, si el uso de la pila de funciones, como lo determina el compilador, está disponible como salida del proceso de compilación.

Digámoslo de otra manera: ¿es posible conocer el tamaño de todos los objetos locales de una función? Creo que la optimización del compilador no será mi amiga, porque algunas variables desaparecerán, pero un límite superior está bien.


No en general El problema de la detención en la informática teórica sugiere que no se puede predecir si un programa general se detiene en una entrada determinada. Cálculo de la pila utilizada para ejecutar un programa en general sería aún más complicado. Entonces: no. Quizás en casos especiales.

Digamos que tiene una función recursiva cuyo nivel de recursión depende de la entrada que puede ser de longitud arbitraria y ya no tiene suerte.


Solo el compilador lo sabría realmente, ya que es el tipo que junta todas tus cosas. Tendría que mirar el ensamblaje generado y ver cuánto espacio está reservado en el preámbulo, pero eso realmente no cuenta para cosas como alloca que hacen lo suyo en el tiempo de ejecución.


Suponiendo que está en una plataforma incrustada, puede encontrar que su cadena de herramientas tiene algo que hacer. Los buenos compiladores incorporados comerciales (como, por ejemplo, el compilador Arm / Keil) a menudo producen informes del uso de la pila.

Por supuesto, las interrupciones y la recursividad suelen ser un poco más allá de ellos, pero te da una idea aproximada si alguien ha cometido un terrible error con un búfer de varios megabytes en la pila en alguna parte.


El código del kernel de Linux se ejecuta en una pila de 4K en x86. Por eso les importa. Lo que utilizan para comprobarlo es una secuencia de comandos de perl que escribieron, que puede encontrar como scripts / checkstack.pl en un archivo kernel reciente (2.6.25 lo tiene). Se ejecuta en el resultado de objdump, la documentación de uso está en el comentario inicial.

Creo que ya lo utilicé para binarios de espacio de usuario hace años, y si conoces un poco de programación de perl, es fácil arreglarlo si está roto.

De todos modos, lo que básicamente hace es mirar automáticamente la salida de GCC. Y el hecho de que los hackers kernel escribieron tal herramienta significa que no hay una forma estática de hacerlo con GCC (o tal vez que se haya agregado recientemente, pero lo dudo).

Por cierto, con objdump del proyecto mingw y ActivePerl, o con Cygwin, debería poder hacer eso también en Windows y también en binarios obtenidos con otros compiladores.


No es exactamente "tiempo de compilación", pero lo haría como un paso posterior a la compilación:

  • deja que el vinculador cree un archivo de mapa para ti
  • para cada función en el archivo de mapa, lea la parte correspondiente del ejecutable y analice el prólogo de la función.

Esto es similar a lo que hace StackAnalyzer, pero mucho más simple. Creo que analizar el ejecutable o el desmontaje es la manera más fácil que se puede acceder al resultado del compilador. Aunque el compilador conoce esas cosas internamente, me temo que no podrá obtenerlo (puede pedirle al proveedor del compilador que implemente la funcionalidad, o si usa el compilador de código abierto, puede hacerlo usted mismo o dejar que alguien lo haga). para ti).

Para implementar esto, necesitas:

  • ser capaz de analizar el archivo de mapa
  • entender el formato del ejecutable
  • saber cómo se puede ver el prólogo de una función y ser capaz de "decodificarla"

Cuán fácil o difícil sería esto depende de su plataforma objetivo. (Integrado? ¿Qué arquitectura de CPU? ¿Qué compilador?)

Todo esto definitivamente se puede hacer en x86 / Win32, pero si nunca hiciste algo como esto y tienes que crear todo esto desde cero, pueden pasar algunos días antes de que finalices y tener algo funcionando.


No veo por qué un análisis de código estático no podría dar una cifra lo suficientemente buena para esto.

Es trivial encontrar todas las variables locales en cualquier función dada, y el tamaño de cada variable se puede encontrar a través del estándar C (para tipos incorporados) o mediante el cálculo (para tipos complejos como estructuras y uniones).

Claro, no se puede garantizar que la respuesta sea 100% precisa, ya que el compilador puede hacer varios tipos de optimizaciones como relleno, colocar variables en registros o eliminar completamente variables innecesarias. Pero cualquier respuesta que dé debería ser, al menos, una buena estimación.

Hice una búsqueda rápida en Google y encontré StackAnalyzer, pero creo que otras herramientas de análisis de código estático tienen capacidades similares.

Si quieres una cifra 100% precisa, entonces deberías mirar el resultado del compilador o verificarlo durante el tiempo de ejecución (como sugirió Ralph en su respuesta )


StackAnlyser parece examinar el código ejecutable en sí mismo más alguna información de depuración. Lo que se describe en esta respuesta , es lo que estoy buscando, el analizador de pila parece exagerado para mí.

Algo similar a lo que existe para ADA estaría bien. Mira esta página de manual del manual de Gnat:

22.2 Análisis de uso de Static Stack

Una unidad compilada con -fstack-use generará un archivo adicional que especifica la cantidad máxima de pila utilizada, por función. El archivo tiene el mismo nombre base que el archivo de objeto de destino con una extensión .su. Cada línea de este archivo se compone de tres campos:

* The name of the function. * A number of bytes. * One or more qualifiers: static, dynamic, bounded.

El segundo campo corresponde al tamaño de la parte conocida del cuadro de función.

El calificador estático significa que el tamaño del marco de la función es puramente estático. Por lo general, significa que todas las variables locales tienen un tamaño estático. En este caso, el segundo campo es una medida confiable de la utilización de la pila de funciones.

La dinámica del calificador significa que el tamaño del marco de la función no es estático. Sucede principalmente cuando algunas variables locales tienen un tamaño dinámico. Cuando este calificador aparece solo, el segundo campo no es una medida confiable del análisis de la pila de funciones. Cuando está calificado con delimitado, significa que el segundo campo es un máximo confiable de la utilización de la pila de funciones.