2011-03-13 25 views
6

Estoy trabajando en el código incrustado y por ahora totalmente dependiente de las impresiones dentro de las funciones para descubrir el flujo de ejecución (no hay ninguna funcionalidad de seguimiento de pila disponible).Cómo agregar instrucciones de impresión en cada función en archivos c de forma programática correcta?

A menudo sucede que puse un montón de declaraciones impresas, construí mi código y lo ejecuté solo para darme cuenta de que debería haber puesto las impresiones en una docena de otros lugares también. Y luego comienza el proceso de una hora nuevamente.

¿Hay alguna manera fácil de tomar mis 5 o 6 archivos c que quiero analizar y ejecutar alguna herramienta que entre y agregar una declaración de impresión en cada función? (Esto obviamente tendrá que ser después de las declaraciones de variables ya que está en C)

Aún mejor sería tener una impresión cada vez que hay un if/else o switch/case ... básicamente cualquier instrucción condicional.

+1

Buena suerte escribiendo una expresión regular para hacer eso. – karlphillip

Respuesta

1

puede usar macros como esto

#define begin {printf(__func__##" Started"); 
#define end printf(__func__##" Ended");} 

y luego vuelva a colocar todos sus {, } con Begin y macros finales (__func__ es una macro cuyo nombre función de retorno y se define en C99 también hay otras macros equvalent para otros compiladores)

+1

gracias, esto es realmente útil. No sabía sobre esta macro. Google también encontró un poco sobre __PRETTY_FUNCTION__ , pero el problema es que si hago que la macro ponga la impresión (en realidad no es una impresión, es una variación para nuestro entorno) en la parte superior, habrá muchos errores de compilación debido a las declaraciones var que ya no estarían en la parte superior. Del mismo modo, el final tendría problemas debido a la posibilidad de varias devoluciones aquí y allá. Todavía estaría contento con solo la macro de inicio si pudiera ponerse de alguna manera al final de las declaraciones de variables en cada función. – user657862

0

por sólo 5-6 archivos me gustaría ir manualmente y añadir una impresión ("nombre de función") macro en cada función y luego definir que a cualquier salida de la cadena, o nada

Puede usar ctags para analizar los archivos y compilarlo automáticamente, pero a menos que tenga 100s de archivos, sería más rápido hacerlo a mano

+0

sí ... esa es la cuestión ... estos archivos tienen muchas funciones y estoy seguro de que tendré que hacer esto en el futuro también ... por eso estaba buscando hacerlo programáticamente ... si nada funciona entonces esto es lo que haré :) – user657862

9

No declara el compilador que está utilizando, pero gcc tiene una muy práctico interruptor:

-finstrument-functions 

que inserta una llamada especial en cada entrada y salida de función. Puede compilar solo los archivos relevantes con este ajuste, sin necesidad de modificar el código fuente.

Las llamadas se realizan a dos funciones que debe crear:

 void __cyg_profile_func_enter (void *this_fn, 
            void *call_site); 
     void __cyg_profile_func_exit (void *this_fn, 
            void *call_site); 

ETRACE es una herramienta diseñada para la explotación de este para crear rastreos de llamadas, vea http://ndevilla.free.fr/etrace/

+0

gracias. No estoy usando gcc, pero le preguntaré a los gurús de C en mi compañía que existe algo similar. – user657862

0

Si vim es su editor favorito puede instalar este complemento: http://www.vim.org/scripts/script.php?script_id=213 y personaliza la plantilla relacionada. Puede ser útil para muchas tareas diferentes. (Funciona para las nuevas funciones que definirá, ese no es su caso pero podría ser útil para uso futuro)

+0

Uso sourceinsight y notepad ++ pero verifico esto. ¡Gracias! – user657862

0

Le recomendaría que use un depurador, como GBD. De esta forma, incluso puede ejecutar su programa "paso a paso" y analizar tales condiciones. No veo una razón para imprimir algo en cada función.

+0

Esa razón existe. Cuando quise averiguar por qué y dónde ghostscript hizo un juicio radicalmente diferente basado en una pequeña modificación en el lado de la entrada, al comparar dos rastros de llamadas de 1,5 gb se reveló rápidamente el punto de bifurcación. Buena suerte al pasar por un programa de este tipo utilizando gdb ... ;-) – mvds

+0

@mvds ¡Ciertamente señor, razón aceptada! :-) De todos modos, no quería decir que el programa puede ejecutarse paso a paso, solo que esta puede ser una herramienta útil. Quién sabe que esto no es lo que el OP está buscando ... Pero gracias por señalar ese caso. No soy un gran maestro de C, solo estoy aprendiendo todos los días. – sidyll

+0

No creo que pueda usar eso en mi caso ... Está en un dispositivo incrustado. Aparentemente hay depuradores JTAG que se pueden usar pero aún no tengo uno. – user657862

Cuestiones relacionadas