Détection de code mort dans le projet legacy C / C++ [fermé]
comment procéderiez-vous à la détection de code mort en code C/C++? J'ai une base de code assez large pour travailler avec et au moins 10-15% est du code mort. Existe-t-il un outil Unix pour identifier ces zones? Certains morceaux de code utilisent encore beaucoup de préprocesseur, peut processus automatisé gérer cela?
8 réponses
vous pouvez utiliser un outil d'analyse de couverture de code pour cela et chercher des spots inutilisés dans votre code.
un outil populaire pour la chaîne d'outils gcc est gcov, avec l'interface 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'option '--coverage'. Ensuite, lancez votre application ou lancez votre suite de test avec cette construction compatible gcov.
essentiellement gcc émettra des fichiers supplémentaires pendant la compilation et l'application émettra aussi des données de couverture pendant l'exécution. Vous devez collecter toutes ces (.gcdo et .gcda fichiers). 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 d'une 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 à travers la lcov toolsuite. Fusion de tous les fichiers de couverture de différents essais est également possible, quoique un peu en cause.
quoi qu'il en soit, vous vous retrouvez avec un bel ensemble de pages Web montrant quelques informations de couverture, en soulignant les morceaux de code qui n'ont pas de couverture et donc, n'ont pas été utilisés.
hors cours, vous devez revérifier si les portions de code ne sont pas utilisées dans n'importe quelle situation et beaucoup dépend de la façon dont vos tests exercent le codebase. Mais au moins, Cela donnera une idée sur les candidats possibles de code mort...
compilez-le sous gcc avec le code-Wunreachable.
je pense que plus la version est récente, plus vous obtiendrez de meilleurs résultats, mais j'ai l'impression que c'est quelque chose sur lequel ils ont travaillé activement. Notez que cela fait analyse de flux, mais je ne crois pas qu'il vous parle de "code" qui est déjà mort au moment où il quitte le préprocesseur, parce que ce n'est jamais analysé par le compilateur. Il ne détectera pas non plus, par exemple, les fonctions exportées qui sont jamais appelé, ou le code de gestion de cas spécial qui se trouve être impossible parce que rien n'appelle jamais la fonction avec ce paramètre - vous avez besoin de couverture de code pour cela (et exécuter les tests fonctionnels, pas les tests unitaires. Les tests unitaires sont supposé d'avoir une couverture de code de 100%, et donc d'exécuter des chemins de code qui sont "morts" en ce qui concerne l'application). Néanmoins, avec ces limites à l'esprit, il est un moyen facile de commencer à trouver le plus complètement bollixed routines dans la base de code.
cet avis du CERT énumère d'autres outils pour la détection de code mort statique
votre approche dépend des tests de disponibilité (automatisés). Si vous avez une suite de test en qui vous avez confiance pour couvrir une quantité suffisante de fonctionnalité, 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 pourriez vouloir regarder dans les outils d'analyse de code source comme SciTools comprendre qui peut vous aider à analyser votre code en utilisant un grand nombre de 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 très rapides de correction de bugs et de réponses aux questions.
j'ai trouvé une page sur analyse de code source statique qui liste de nombreux autres outils ainsi.
si cela ne vous aide pas suffisamment non plus, et que vous êtes particulièrement intéressé à découvrir le code mort lié au préprocesseur, Je je vous recommande de poster plus de détails sur le code. Par exemple, si elle est principalement liée à diverses combinaisons de paramètres #ifdef, vous pouvez écrire des scripts pour déterminer les (combinaisons de) paramètres et trouver quelles combinaisons ne sont jamais réellement construites, etc.
g++ 4.01 -Wunreachable-code met en garde sur le code qui est inaccessible à l'intérieur d'une fonction, mais ne pas avertir à propos des fonctions inutilisées.
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 émettra un avertissement au sujet du point b, mais ne dira rien au sujet de foo() (point a) même s'il est inaccessible dans ce fichier. Ce comportement est correct bien que décevant, parce qu'un compilateur ne peut pas savoir que la fonction foo () n'est pas déclarée externe dans une autre unité de compilation et invoquée à partir de là; seulement un l'éditeur de liens peut être sûr.
pour le code C seulement et en supposant que le code source de l'ensemble du projet est disponible, lancer une analyse avec l'outil Open Source Frama-c . Toute instruction du programme qui s'affiche en rouge dans l'interface graphique est code mort.
si vous avez des problèmes de "code mort", vous pourriez aussi être intéressé par
suppression du "code de rechange", code qui est exécuté mais ne l'est pas
contribuer au résultat final. Cela exige que vous fournissiez
une modélisation précise des entrées/sorties fonctions (vous ne voudriez pas
pour supprimer un calcul qui semble être "libres", mais
qui est utilisé comme un argument à printf
). Frama-c a une option pour pointer le code de rechange.
les deux Mozilla et Open Office ont des solutions locales.
analyse de code mort comme ceci nécessite une analyse globale de votre projet entier. Vous ne pouvez pas obtenir cette information en analysant les unités de traduction individuellement (bien, vous pouvez détecter les entités mortes si elles sont entièrement dans une seule unité de traduction, mais je ne pense pas que ce soit ce que vous recherchez vraiment).
nous avons utilisé notre boîte à outils de réingénierie de logiciel DMS pour implémenter exactement ceci pour le code Java, en analysant toutes les unités de compilation impliquées à la fois, construire des tables de symboles pour tout et traquer toutes les références. Une définition de niveau supérieur sans référence et sans prétention d'être un élément externe de L'API est morte. Cet outil supprime aussi automatiquement le code mort, et à la fin vous pouvez choisir ce que vous voulez: le rapport des entités mortes, ou le code retiré de ces entités.
DMS analyse également le C++ dans une variété de dialectes (EDIT Feb 2014: incluant les versions MS et GCC de C++14 [EDIT Nov 2017: now C++17] ) et construit toutes les tables de symboles nécessaires. Trouver les références mortes serait simple à partir de ce point. Les DMS pourraient également être utilisés pour les enlever. Voir http://www.semanticdesigns.com/Products/DMS/DMSToolkit.html