web-dev-qa-db-fra.com

Détection de code mort dans un projet C / C ++ hérité

Comment aborderiez-vous la détection de code mort dans le code C/C++? J'ai une base de code assez grande pour travailler avec et au moins 10-15% est du code mort. Existe-t-il un outil basé sur Unix pour identifier ces zones? Certains morceaux de code utilisent encore beaucoup de préprocesseur, le processus automatisé peut-il gérer cela?

68
Nazgob

Pour cela, vous pouvez utiliser un outil d'analyse de couverture de code et rechercher les emplacements inutilisés dans votre code.

Un outil populaire pour la chaîne d'outils gcc est gcov, avec le frontal graphique lcov ( http://ltp.sourceforge.net/coverage/lcov.php ).

Si vous utilisez gcc, vous pouvez compiler avec le support gcov, qui est activé par l'indicateur '--coverage'. Ensuite, exécutez votre application ou exécutez votre suite de tests avec cette version compatible gcov.

Fondamentalement, gcc émettra des fichiers supplémentaires lors de la compilation et l'application émettra également des données de couverture lors de l'exécution. Vous devez collecter tous ces éléments (fichiers .gcdo et .gcda). Je ne vais pas en détail ici, mais vous devez probablement définir deux variables d'environnement pour collecter les données de couverture de manière saine: GCOV_PREFIX et GCOV_PREFIX_STRIP ...

Après l'exécution, vous pouvez rassembler toutes les données de couverture et les exécuter via la suite d'outils lcov. La fusion de tous les fichiers de couverture de différents tests est également possible, quoique un peu compliquée.

Quoi qu'il en soit, vous vous retrouvez avec un bel ensemble de pages Web montrant des informations de couverture, soulignant les morceaux de code qui n'ont aucune couverture et, par conséquent, n'ont pas été utilisés.

Bien sûr, vous devez vérifier si les portions de code ne sont utilisées dans aucune situation et cela dépend beaucoup de la qualité de vos tests pour exercer la base de code. Mais au moins, cela donnera une idée des candidats possibles au code mort ...

30
Johan

Compilez-le sous gcc avec -Wunreachable-code.

Je pense que plus la version est récente, meilleurs seront les résultats, mais je peux me tromper dans mon impression que c'est quelque chose sur lequel ils ont activement travaillé. Notez que cela fait une analyse de flux, mais je ne pense pas qu'il vous parle de "code" qui est déjà mort au moment où il quitte le préprocesseur, car il n'est jamais analysé par le compilateur. Il ne détectera pas non plus, par exemple fonctions exportées qui ne sont jamais appelées, ou code de gestion de cas particulier qui s'avère impossible car rien n'appelle jamais la fonction avec ce paramètre - vous avez besoin d'une couverture de code pour cela (et exécutez les tests fonctionnels, pas les tests unitaires. Les tests unitaires sont supposé avoir une couverture de code à 100%, et donc exécuter des chemins de code qui sont "morts" en ce qui concerne l'application). Pourtant, avec ces limitations à l'esprit, c'est un moyen facile de commencer à trouver les routines les plus complètement bollixées dans la base de code.

Cet avis CERT répertorie d'autres outils pour la détection de code mort statique

17
Steve Jessop

Pour le code C uniquement et en supposant que le code source de l'ensemble du projet est disponible, lancez une analyse avec l'outil Open Source Frama-C . Toute instruction du programme qui affiche du rouge dans l'interface graphique est un code mort.

Si vous rencontrez des problèmes de "code mort", vous pouvez également être intéressé par la suppression du "code de rechange", code qui est exécuté mais qui ne contribue pas au résultat final. Cela vous oblige à fournir une modélisation précise des fonctions d'E/S (vous ne voudriez pas supprimer un calcul qui semble être "de rechange" mais qui est utilisé comme argument pour printf). Frama-C a une option pour indiquer le code de rechange.

4
Pascal Cuoq

Votre approche dépend des tests de disponibilité (automatisés). Si vous disposez d'une suite de tests à laquelle vous faites confiance pour couvrir une quantité suffisante de fonctionnalités, vous pouvez utiliser une analyse de couverture, comme les réponses précédentes l'ont déjà suggéré.

Si vous n'êtes pas aussi chanceux, vous voudrez peut-être examiner des outils d'analyse de code source comme SciTools 'Comprendre cela peut vous aider à analyser votre code à l'aide de nombreux rapports d'analyse intégrés. Mon expérience avec cet outil date d'il y a 2 ans, donc je ne peux pas vous donner beaucoup de détails, mais ce dont je me souviens, c'est qu'ils avaient un support impressionnant avec des délais d'exécution très rapides des corrections de bugs et des réponses aux questions.

J'ai trouvé une page sur analyse de code source statique qui répertorie également de nombreux autres outils.

Si cela ne vous aide pas suffisamment non plus, et que vous souhaitez spécifiquement découvrir le code mort lié au préprocesseur, je vous recommande de publier plus de détails sur le code. Par exemple, s'il est principalement lié à diverses combinaisons de paramètres #ifdef, vous pouvez écrire des scripts pour déterminer les (combinaisons de) paramètres et savoir quelles combinaisons ne sont jamais réellement construites, etc.

4
andreas buykx

Mozilla et Open Office ont tous deux des solutions maison.

4
Max Lybbert

Une analyse de code mort comme celle-ci nécessite une analyse globale de l'ensemble de votre projet. Vous ne pouvez pas obtenir ces informations en analysant les unités de traduction individuellement (eh bien, vous pouvez détecter des entités mortes si elles se trouvent entièrement dans une seule unité de traduction, mais je ne pense pas que ce soit vraiment ce que vous recherchez).

Nous avons utilisé notre DMS Software Reengineering Toolkit pour implémenter exactement ceci pour Java code, en analysant toutes les unités de compilation impliquées en même temps, en construisant des tables de symboles pour tout et en recherchant toutes les références. définition de haut niveau sans références et sans prétention d'être un élément API externe est morte. Cet outil supprime également automatiquement le code mort, et à la fin, vous pouvez choisir ce que vous voulez: le rapport des entités mortes, ou le code dépouillé de ces entités.

DMS analyse également C++ dans une variété de dialectes (EDIT février 2014: y compris les versions MS et GCC de C++ 14 [EDIT nov 2017: maintenant C++ 17] ) et construit toutes les tables de symboles nécessaires . La recherche des références mortes serait simple à partir de ce moment. Le DMS pourrait également être utilisé pour les supprimer. Voir http://www.semanticdesigns.com/Products/DMS/DMSToolkit.html

3
Ira Baxter

Bullseye l'outil de couverture serait utile. Ce n'est pas gratuit cependant.

1
Ashwin