Tengo una aplicación grande escrita en C + POSIX, hay muchas funciones que nunca se llaman dentro de ella. Sin embargo, debido al tamaño del código, es difícil rastrearlos manualmente.
Algunas personas sugirieron usar gcc con -Wunused
y lto, pero no devolvió ninguna función utilizada, mientras que sigo encontrando y eliminando algunas manualmente.
Así que creo que necesito una herramienta de cobertura de código para analizar el programa en tiempo de ejecución. Peoples me sugirió gcov o valgrind, pero no pude encontrar cómo usarlos para imprimir una lista de funciones muertas. gcov solo reveló que solo se usa el 68% de las funciones compiladas, pero no tengo ninguna forma de enumerarlas.
Entonces, ¿alguien conoce una buena herramienta, y si es así, dígame exactamente cómo puedo usarla para ese propósito (un ejemplo de línea de comando sería bienvenido) ?
Eliminé todas las funciones que no se usan en el código fuente. Solo funciones como esta permanecen dentro del código fuente:
if(conditional statement) {
some stuff;
dead_function();
some_stuff;
}
Where conditional statement
nunca es verdadero en tiempo de ejecución, y la eliminación de dead_function()
conduciría a la eliminación de la declaración para evitar errores indefinidos.
Dado que @user2284570 se encuentra en la cómoda situación de cubrir el 100 % de los casos de uso a través de pruebas, el análisis de código dinámico proporcionará la respuesta. En otros casos de destitución de funciones, sus convocatorias y condiciones requerirían una revisión minuciosa.
Cualquier herramienta de cobertura de código informará la cobertura de funciones de una forma u otra. La queja principal parece ser el informe de la ubicación exacta de las funciones no utilizadas (aquí: muertas). No puedo hablar por otras herramientas, pero nuestra empresa tiene una opción de informe de formato de texto que presenta marcadores de posición para el nombre del archivo de origen y los datos de línea. Dado que se solicitó un ejemplo de línea de comando concreto, aquí hay uno:
$ csgcc -o myapp mycode.c
$ ./myapp --run-all-tests
$ cmcsexeimport -m myapp.csmes -e myapp.csexe --title=mytests
$ cmreport --function-coverage -m myapp.csmes --format-unexecuted='%f:%l'
Esto imprimirá las ubicaciones de funciones muertas como:
mycode.c:101
mycode.c:213
mycode.c:1032
Un estudiante universitario local redactó instrucciones más detalladas para este enfoque.
Después de eliminar las funciones no utilizadas, también querrá analizar la cobertura de sucursales y eliminar las declaraciones if() superfluas y otras. Solo tenga cuidado con los efectos secundarios de las expresiones evaluadas. Pero afortunadamente, su cobertura de código perfecta detectará regresiones.
Puede usar splint
con la alluse
bandera para verificar funciones no utilizadas, pero personalmente lo usaría doxygen
para producir un mapa de llamadas : cualquier función que no tenga padres probablemente no se use, solo busque cualquier función que esté en las tablas de funciones que no se pueden llamar directamente pero cosas como las máquinas de estado pueden invocarse desde el índice de la tabla.
Doxygen es una herramienta invaluable para manejar grandes bases de código y vale la pena aprender a usarla en cualquier caso, es gratis y está disponible para múltiples plataformas, también tiende a fomentar la documentación de su código sobre la marcha.
En el caso de un código que se llama pero solo desde un código inalcanzable, tendrá que usar una herramienta de análisis estático completo como LDRA (costosa), que le indicará el código inalcanzable. En este caso, es mejor eliminar primero todo el código inalcanzable y luego buscar funciones no llamadas. Alternativamente, necesitará un conjunto de pruebas que esté seguro de que ejerce el 100% de la funcionalidad; luego, puede usar un generador de perfiles o una herramienta de cobertura como gcov en su programa mientras ejecuta su conjunto de pruebas. Si su prueba ha ejercido toda su funcionalidad y tiene partes con 0% de cobertura, entonces no se llaman , pero luego tendrá que encontrar las llamadas que no se pueden alcanzar y eliminar ese código para que el enlazador no se queje de todos modos.
Para responder a su pregunta revisada, si compila todo su código con gcc -fprofile-arcs -ftest-coverage
opciones establecidas y luego ejecuta un conjunto de pruebas que está seguro de que cubre toda la funcionalidad y todas las posibilidades (posiblemente en varias ejecuciones).
La gcov
utilidad espera que usted haga parte del trabajo; no tiene simplemente una opción para "dime qué no se llamó", por lo que tendrá que encontrar esas funciones que no se llamaron.
Puede usargcov
con la opción en cada archivo de origen , --function-summaries
generará un conjunto de archivos de salida que incluirán resúmenes de funciones : busque cualquiera de los que incluyan never
o 0%
para encontrar las funciones no ejecutadas.
Sugeriría agregar una función que sepa que nunca se llamará o conocer una que aún no eliminó; esto le permitirá ver cómo se ve la salida; luego puede usarla grep
para encontrarlos todos.
Su próximo paso será usar grep
o algo similar para ver la gcov
salida de todos los lugares donde esas funciones están presentes en su código; debería ver recuentos de ejecución de 0 para toda la rama que contiene la llamada , esto le dará un buen punto de partida. para extender sus pruebas, para casos de uso que se había perdido , o para eliminar código.
Gilles 'SO- deja de ser malvado'
dead_function
se usa), sino código muerto. ¡Eso requiere técnicas completamente diferentes! Tenga en cuenta que el análisis de tiempo de ejecución solo encontrará código que no se haya ejecutado en una ejecución particular del programa; ese código puede estar vivo en diferentes circunstancias.usuario2284570
Ira Baxter
usuario2284570
steve barnes
Mawg dice que reincorpore a Monica
usuario2284570
usuario2284570
steve barnes
printf(__func__);
como la primera línea, en gcc esto imprimirá el nombre de la función cada vez que se llame; ejecute su prueba capturando la salida, luego no se llamará cualquier nombre que no esté en la salida.usuario2284570
steve barnes
steve barnes
usuario2284570
steve barnes
Mawg dice que reincorpore a Monica
usuario2284570
Mawg dice que reincorpore a Monica