Question

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

Était-ce utile?

La solution

Vous pouvez utiliser un outil d'analyse de la couverture de code pour cela et rechercher des taches inutilisées dans votre code.

Un outil populaire pour la chaîne d’outils gcc est gcov, ainsi que l’interface graphique lcov ( http: / /ltp.sourceforge.net/coverage/lcov.php ).

Si vous utilisez gcc, vous pouvez compiler avec le support gcov, activé par le drapeau '--coverage'. Ensuite, lancez votre application ou votre suite de tests avec cette version compatible avec gcov.

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

Après l’exécution, vous pouvez rassembler toutes les données de couverture et les exécuter dans la suite d’outils lcov. La fusion de tous les fichiers de couverture de différentes exécutions de test est également possible, même si elle est un peu compliquée.

Quoi qu'il en soit, vous vous retrouvez avec une belle série de pages Web contenant des informations sur la couverture, indiquant les éléments de code non couverts et, par conséquent, non utilisés.

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

Autres conseils

Compilez-le sous gcc avec le code -Wunreachable-code.

Je pense que plus la version est récente, plus vous obtiendrez de meilleurs résultats, mais je peux me tromper d’avoir l’impression que c’est quelque chose sur lequel ils travaillent activement. Notez que ceci est une analyse de flux, mais je ne crois pas que cela vous parle de " code " qui est déjà mort au moment où il quitte le préprocesseur, car cela n’a jamais été analysé par le compilateur. Il ne détectera pas par exemple fonctions exportées qui ne sont jamais appelées, ou code spécial de gestion de cas qui est 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 supposons avoir une couverture de code à 100% et donc exécuter des chemins de code qui sont "morts" en ce qui concerne l'application). Malgré tout, avec ces limitations à l’esprit, c’est un moyen facile de commencer à rechercher les routines les plus complètement corrigées dans la base de code.

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

Votre approche dépend des tests de disponibilité (automatisés). Si vous comptez sur une suite de tests pour couvrir un nombre suffisant de fonctionnalités, vous pouvez utiliser une analyse de la couverture, comme suggéré précédemment dans les réponses.

Si vous n'êtes pas aussi chanceux, vous voudrez peut-être consulter des outils d'analyse du code source tels que SciTools 'Comprenez que cela peut vous aider à analyser votre code en utilisant de nombreux rapports d’analyse intégrés. Mon expérience avec cet outil remonte à 2 ans. Je ne peux donc pas vous donner beaucoup de détails, mais ce dont je me souviens, c’est qu’ils bénéficiaient d’un support impressionnant avec des délais très courts pour la résolution des bogues et les réponses aux questions.

J'ai trouvé dans une analyse de code source statique une liste répertoriant de nombreux autres outils.

Si cela ne vous aide pas suffisamment non plus et que vous souhaitez en savoir plus sur le code mort lié au préprocesseur, je vous recommanderais de publier davantage 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.

g ++ 4.01 -Wunreachable-code met en garde sur le code inaccessible dans une fonction, mais pas sur les 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 sur le point b, mais ne dira rien sur foo () (point a), même s’il est inaccessible dans ce fichier. Ce comportement est correct bien que décevant, car un compilateur ne peut pas savoir que la fonction foo () n’est pas déclarée extern dans une autre unité de compilation et invoquée à partir de là; seul un éditeur de liens peut en être sûr.

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 s'affiche en rouge dans l'interface graphique est code mort.

Si vous avez un " code mort " problèmes, vous pouvez également être intéressé par supprimer le "code de secours", le code qui est exécuté mais ne fonctionne pas contribuer au résultat final. Cela nécessite que vous fournissiez une modélisation précise des fonctions d'E / S (vous ne voudriez pas pour supprimer un calcul qui semble être "en réserve" mais qui est utilisé comme argument de printf ). Frama-C a une option pour indiquer le code de secours.

Les deux Mozilla et Open Office propose des solutions développées en interne.

Une telle analyse de code mort 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 les entités mortes si elles appartiennent entièrement à une seule unité de traduction, mais je ne pense pas que ce soit ce que vous recherchez vraiment.)

Nous avons utilisé notre outil DMS Software Reengineering Toolkit pour implémenter cela exactement en code Java, en analysant toutes les unités de compilation impliquées, en construisant des tables de symboles pour tout et en recherchant toutes les références. Une définition de niveau supérieur sans références et aucune revendication d'être un élément d'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ébarrassé de ces entités.

DMS analyse également le langage 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. Traquer les références mortes serait simple à partir de là. DMS pourrait également être utilisé pour les éliminer. Voir http://www.semanticdesigns.com/Products/DMS/DMSToolkit.html

Un

outil de couverture Bullseye serait utile. Ce n’est pas gratuit, cependant.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top