Pregunta

¿Cómo abordaría la detección de código muerto en el código C / C ++? Tengo una base de código bastante grande para trabajar y al menos 10-15% es código muerto. ¿Hay alguna herramienta basada en Unix para identificar estas áreas? Algunas piezas de código todavía usan mucho preprocesador, ¿el proceso automatizado puede manejar eso?

¿Fue útil?

Solución

Puede usar una herramienta de análisis de cobertura de código para esto y buscar puntos no utilizados en su código.

Una herramienta popular para gcc toolchain es gcov, junto con la interfaz gráfica lcov ( http: / /ltp.sourceforge.net/coverage/lcov.php ).

Si usa gcc, puede compilar con el soporte de gcov, que está habilitado por el indicador '--coverage'. A continuación, ejecute su aplicación o ejecute su conjunto de pruebas con esta compilación habilitada con gcov.

Básicamente, gcc emitirá algunos archivos adicionales durante la compilación y la aplicación también emitirá algunos datos de cobertura mientras se ejecuta. Tienes que recopilar todos estos (archivos .gcdo y .gcda). No voy a detallarlo aquí, pero es probable que necesite configurar dos variables de entorno para recopilar los datos de cobertura de una manera razonable: GCOV_PREFIX y GCOV_PREFIX_STRIP ...

Después de la ejecución, puede reunir todos los datos de cobertura y ejecutarlos a través del conjunto de herramientas lcov. La fusión de todos los archivos de cobertura de diferentes ejecuciones de prueba también es posible, aunque un poco involucrado.

De todos modos, terminas con un buen conjunto de páginas web que muestran información de cobertura, señalando los fragmentos de código que no tienen cobertura y, por lo tanto, no se usaron.

Por supuesto, necesita volver a verificar si las partes del código no se usan en cualquier situación y mucho depende de qué tan buenas sean sus pruebas en el código base. Pero al menos, esto dará una idea sobre posibles candidatos a código muerto ...

Otros consejos

Compílalo bajo gcc con -Wunreachable-code.

Creo que cuanto más reciente sea la versión, mejores resultados obtendrás, pero puedo estar equivocado en mi impresión de que es algo en lo que han estado trabajando activamente. Tenga en cuenta que esto hace un análisis de flujo, pero no creo que le informe sobre " código " que ya está muerto cuando sale del preprocesador, porque el compilador nunca lo analiza. Tampoco detectará, por ejemplo. funciones exportadas que nunca se llaman, o código especial de manejo de casos que resulta imposible porque nada llama a la función con ese parámetro; necesita la cobertura del código para eso (y ejecute las pruebas funcionales, no las pruebas unitarias. Las pruebas unitarias son se supone que tiene una cobertura de código del 100% y, por lo tanto, ejecuta rutas de código que están 'muertas' en lo que respecta a la aplicación). Aún así, con estas limitaciones en mente, es una forma fácil de comenzar a encontrar las rutinas más completamente mezcladas en la base de código.

Este aviso CERT enumera algunas otras herramientas para la detección de código muerto estático

Su enfoque depende de las pruebas de disponibilidad (automatizadas). Si tiene un conjunto de pruebas en el que confía para cubrir una cantidad suficiente de funcionalidad, puede usar un análisis de cobertura, como ya se sugirió en las respuestas anteriores.

Si no es tan afortunado, puede buscar herramientas de análisis de código fuente como SciTools 'Comprenda que puede ayudarlo a analizar su código usando muchos informes de análisis integrados. Mi experiencia con esa herramienta data de hace 2 años, por lo que no puedo darles muchos detalles, pero lo que sí recuerdo es que tuvieron un apoyo impresionante con tiempos de respuesta muy rápidos de correcciones de errores y respuestas a preguntas.

Encontré una página en análisis de código fuente estático que también enumera muchas otras herramientas.

Si eso tampoco te ayuda lo suficiente, y estás específicamente interesado en descubrir el código muerto relacionado con el preprocesador, te recomendaría que publiques más detalles sobre el código. Por ejemplo, si está relacionado en su mayoría con varias combinaciones de configuraciones #ifdef, podría escribir scripts para determinar las (combinaciones de) configuraciones y descubrir qué combinaciones nunca se construyen realmente, etc.

g ++ 4.01 -Wunreachable-code advierte sobre el código que es inalcanzable dentro de una función, pero no advierte sobre funciones no utilizadas.

int foo() { 
    return 21; // point a
}

int bar() {
  int a = 7;
  return a;
  a += 9;  // point b
  return a;
}

int main(int, char **) {
    return bar();
}

g ++ 4.01 emitirá una advertencia sobre el punto b, pero no diga nada sobre foo () (punto a) a pesar de que no se puede acceder a este archivo. Este comportamiento es correcto aunque decepcionante, porque un compilador no puede saber que la función foo () no se declara externa en ninguna otra unidad de compilación y se invoca desde allí; solo un enlazador puede estar seguro.

Solo para el código C y suponiendo que el código fuente de todo el proyecto está disponible, inicie un análisis con la herramienta de Código abierto Frama-C . Cualquier declaración del programa que se muestra en rojo en la GUI es código muerto.

Si tienes " código muerto " problemas, también te puede interesar eliminando " código de repuesto " ;, código que se ejecuta pero no Contribuir al resultado final. Esto requiere que usted proporcione una modelación precisa de las funciones de E / S (no querría para eliminar un cálculo que parece ser " repuesto " pero que se utiliza como argumento para printf ). Frama-C tiene una opción para señalar el código de repuesto.

Ambos Mozilla y Open Office tiene soluciones propias.

El análisis de código muerto como este requiere un análisis global de todo su proyecto. No puede obtener esta información analizando las unidades de traducción individualmente (bueno, puede detectar entidades muertas si están completamente dentro de una sola unidad de traducción, pero no creo que eso sea lo que realmente está buscando).

Hemos utilizado nuestro kit de herramientas de reingeniería de software DMS para implementar exactamente esto para el código Java, analizando todas las unidades de compilación involucradas a la vez, construyendo tablas de símbolos para todo y buscando todas las referencias. Una definición de nivel superior sin referencias y sin reclamo de ser un elemento API externo está muerta. Esta herramienta también elimina automáticamente el código muerto, y al final puede elegir lo que desee: el informe de entidades muertas o el código eliminado de esas entidades.

DMS también analiza C ++ en una variedad de dialectos (EDITAR Feb 2014: incluidas las versiones MS y GCC de C ++ 14 [EDITAR Nov 2017: ahora C ++ 17] ) y crea todas las tablas de símbolos necesarias. Rastrear las referencias muertas sería sencillo desde ese punto. El DMS también podría usarse para eliminarlos. Consulte http://www.semanticdesigns.com/Products/DMS/DMSToolkit.html

herramienta de cobertura Bullseye sería de ayuda. Aunque no es gratis.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top