Quelle est l'utilité de l'analyse dynamique lorsque vous avez une analyse statique?

Afin de vérifier la qualité du logiciel, vous devez utiliser de nombreux outils différents, y compris des analyseurs statiques et dynamiques. Dans cet article, nous allons essayer de comprendre pourquoi un seul type d'analyse, statique ou dynamique, peut ne pas être suffisant pour une analyse logicielle complète et pourquoi il est préférable d'utiliser les deux.

Figure 1


Notre équipe écrit beaucoup sur l'utilité de l'analyse statique et les avantages qu'elle apporte à vos projets. Nous aimons exécuter notre outil sur divers projets open-source pour trouver d'éventuels bogues, ce qui est notre façon de vulgariser la méthode d'analyse de code statique. À son tour, l'analyse statique contribue à rendre les programmes de meilleure qualité et plus fiables et à réduire le nombre de vulnérabilités potentielles. Peut-être que tous ceux qui sont directement impliqués dans le travail sur le code source ont ce sentiment de satisfaction d'avoir corrigé des bogues. Mais même si le processus de détection (et de correction) des bogues ne déclenche pas vos endorphines, vous appréciez certainement l'idée de réduire les dépenses de développement grâce à l'analyseur statique, qui a aidé vos programmeurs à utiliser leur temps plus efficacement et plus efficacement. Pour en savoir plus sur les avantages de l'utilisation de l'analyse statique en termes d'argent, consultez cet article . Il donne une estimation approximative pour PVS-Studio, mais ces résultats peuvent être extrapolés à d'autres outils d'analyse statique disponibles sur le marché.

Tout ce qui précède semble suggérer que le but de l'analyse statique est de trouver les bogues dans le code source le plus tôt possible, réduisant ainsi les dépenses de correction des bogues. Mais pourquoi avons-nous alors besoin d'une analyse dynamique, et pourquoi s'en tenir à l'une des deux techniques peut être insuffisant? Donnons des définitions plus formelles et plus claires des analyses statiques et dynamiques et essayons de répondre à ces questions.

L'analyse de code statique est le processus de détection des erreurs et des odeurs de code dans le code source du logiciel. Pour analyser un programme, vous n'avez pas besoin de l'exécuter; l'analyse sera effectuée sur la base de code disponible. L'analogie la plus proche de l'analyse statique est ce qu'on appelle la révision de code, sauf que l'analyse statique est une version automatisée de la révision de code (c'est-à-dire effectuée par un programme de bot).

Les principaux avantages de l'analyse statique:

  1. Détection de bogues aux premiers stades de développement. Cela aide à rendre la correction de bogues beaucoup moins chère, car plus tôt un défaut est détecté, plus il est facile - et, par conséquent, moins cher - de le corriger.
  2. Il vous permet de localiser précisément le bogue potentiel dans le code source.
  3. Couverture complète du code. Quelle que soit la fréquence à laquelle un bloc de code ou un autre prend le contrôle lors de l'exécution, l'analyse statique vérifie la base de code entière.
  4. Facile à utiliser. Vous n'avez pas besoin de préparer d'ensembles de données d'entrée pour effectuer une vérification.
  5. Les analyseurs statiques détectent les fautes de frappe et les erreurs liées au copier-coller assez rapidement et facilement.

Les inconvénients objectifs de l'analyse statique:

  1. Faux positifs inévitables. Un analyseur statique peut se mettre en colère contre les fragments de code qui ne contiennent en fait aucun bogue. Seul le programmeur peut résoudre ce problème et marquer un avertissement comme un faux positif, ce qui signifie que cela prendra une partie de son temps de travail.
  2. L'analyse statique est généralement mauvaise pour détecter les fuites de mémoire et les erreurs liées à la concurrence. Pour détecter de telles erreurs, vous devez en fait exécuter une partie du programme en mode virtuel, ce qui est une tâche extrêmement difficile. En outre, de tels algorithmes nécessiteraient trop de mémoire et de temps CPU. Les analyseurs statiques ne vont généralement pas plus loin que l'analyse de cas simples. Les analyseurs dynamiques sont plus aptes à diagnostiquer les fuites de mémoire et les erreurs liées à la concurrence.

Il convient de noter que les analyseurs statiques ne se concentrent pas exclusivement sur la capture de bogues. Par exemple, ils peuvent fournir des recommandations sur la mise en forme du code. Certains outils vous permettent de vérifier la conformité de votre code avec la norme de codage à laquelle votre entreprise se conforme. Cela inclut l'indentation de diverses constructions, l'utilisation de caractères d'espace / tabulation, etc. De plus, l'analyse statique peut être utile pour mesurer les métriques. Une métrique logicielle est une mesure quantitative du degré de propriété d'un programme ou de ses spécifications. Consultez cet article pour en savoir plus sur les autres utilisations de l'analyse statique.

L'analyse de code dynamique est l'analyse effectuée sur un programme au moment de l'exécution. Cela signifie que vous devez d'abord convertir votre code source en un fichier exécutable. En d'autres termes, le code contenant des erreurs de compilation ou de génération ne peut pas être vérifié par ce type d'analyse. La vérification est effectuée avec un ensemble de données d'entrée alimentant le programme en cours d'analyse. C'est pourquoi l'efficacité de l'analyse dynamique dépend directement de la qualité et de la quantité des données d'entrée de test. Ce sont ces données qui déterminent l'étendue de la couverture du code à la fin du test.

Grâce aux tests dynamiques, vous pouvez obtenir les métriques et avertissements suivants:

  1. Ressources utilisées: temps d'exécution de l'ensemble du programme ou de ses parties individuelles, nombre de requêtes externes (par exemple, vers une base de données), quantité de RAM et autres ressources utilisées par le programme.
  2. L'étendue de la couverture du code par les tests et autres mesures.
  3. Bogues logiciels: division par zéro, déréférence nulle, fuites de mémoire, conditions de concurrence.
  4. Quelques failles de sécurité.

Les principaux avantages de l'analyse dynamique:

  1. Vous n'avez pas besoin d'avoir accès au code source du programme pour l'analyser. Il convient de noter, cependant, que les outils d'analyse dynamique se différencient par la façon dont ils interagissent avec le programme analysé (ceci est discuté plus en détail ici ). Par exemple, une technique d'analyse dynamique assez courante implique l'instrumentation du code avant la vérification, c'est-à-dire l'ajout de fragments de code spéciaux au code source de l'application pour que l'analyseur puisse diagnostiquer les erreurs. Dans ce cas, vous devez disposer du code source du programme.
  2. Il peut détecter des erreurs complexes de gestion de la mémoire telles que l'indexation au-delà des limites du tableau et les fuites de mémoire.
  3. Il peut analyser le code multithread au moment de l'exécution, détectant ainsi les problèmes potentiels liés à l'accès aux ressources partagées ou à d'éventuels blocages.
  4. La plupart des implémentations d'analyseurs dynamiques ne génèrent pas de faux positifs car les erreurs sont détectées lorsqu'elles se produisent. Par conséquent, un avertissement émis par un analyseur dynamique n'est pas une prédiction faite par l'outil sur la base de l'analyse du modèle de programme mais une simple déclaration du fait qu'une erreur s'est produite.

Les inconvénients de l'analyse dynamique:

  1. La couverture complète du code n'est pas garantie. Autrement dit, il est très peu probable que vous obteniez une couverture à 100% par des tests dynamiques.
  2. Les analyseurs dynamiques sont mauvais pour détecter les erreurs logiques. Par exemple, une condition toujours vraie n'est pas un bogue du point de vue d'un analyseur dynamique car une telle vérification incorrecte disparaît tout simplement plus tôt à l'étape de compilation.
  3. Il est plus difficile de localiser précisément l'erreur dans le code.
  4. L'analyse dynamique est plus difficile à utiliser que l'analyse statique, car vous devez fournir suffisamment de données au programme pour obtenir de meilleurs résultats et obtenir une couverture de code aussi complète que possible.

L'analyse dynamique est particulièrement utile dans les domaines où la fiabilité du programme, le temps de réponse ou les ressources consommées sont la principale préoccupation. Un système en temps réel gérant un secteur de production critique ou un serveur de base de données sont quelques exemples de tels systèmes. Toute erreur dans ces domaines peut être critique.

Revenant à la question de savoir pourquoi s'en tenir à l'un des deux types d'analyse peut ne pas être suffisant, jetons un coup d'œil à quelques exemples assez triviaux de bogues qu'une méthode d'analyse n'a aucun problème à diagnostiquer tandis que l'autre n'est pas apte à détecter et vice versa.

L'exemple suivant est tiré du projet Clang:

MapTy PerPtrTopDown; MapTy PerPtrBottomUp; void clearBottomUpPointers() { PerPtrTopDown.clear(); } void clearTopDownPointers() { PerPtrTopDown.clear(); } 

Un analyseur statique indiquerait que les corps des deux fonctions sont identiques. Bien sûr, deux fonctions ayant des corps identiques ne sont pas nécessairement un signe définitif de bogue, mais il est très probable qu'elles résultent de l'utilisation de la technique du copier-coller combinée à une négligence du côté du programmeur - et cela conduit à un comportement inattendu. Dans ce cas, la méthode clearBottomUpPointers doit appeler la méthode PerPtrBottomUp.clear . L'analyse dynamique ne remarquerait rien de mal dans cet exemple car c'est un morceau de code absolument légitime de son point de vue.

Un autre exemple. Supposons que nous ayons la fonction suivante:

 void OutstandingIssue(const char *strCount) { unsigned nCount; sscanf_s(strCount, "%u", &nCount); int array[10]; memset(array, 0, nCount * sizeof(int)); } 

En théorie, un analyseur statique pourrait soupçonner qu'il y a quelque chose de mal avec ce code, mais l'implémentation d'un tel diagnostic est une tâche très difficile et inutile. L'exemple est tiré de cet article , qui explique également pourquoi c'est une mauvaise idée d'enseigner aux analyseurs statiques comment diagnostiquer des erreurs comme ça. En bref, les analyseurs statiques sont très mal à comprendre qu'un appel de la fonction memset peut entraîner une indexation au-delà des limites du tableau car ils ne peuvent pas prévoir le nombre qui sera lu à partir de la chaîne strCount ; et si la valeur de strCount est lue dans un fichier, cela devient une tâche impossible pour l'analyse statique. D'un autre côté, un analyseur dynamique n'aurait aucun problème à remarquer et à signaler l'erreur de gestion de la mémoire dans ce code (étant donné que le programme reçoit les bonnes données).

Cet article ne vise pas à comparer les analyses statiques et dynamiques. Il n'existe pas de technique unique permettant de diagnostiquer toute la variété des défauts logiciels. Aucun type d'analyse ne peut remplacer complètement l'autre. Pour améliorer la qualité de vos programmes, vous devrez utiliser différents types d'outils pour qu'ils se complètent. J'espère que les exemples ci-dessus sont suffisamment convaincants.

Je ne souhaite pas avoir l'air trop partisan de l'analyse statique, mais c'est cette technique dont on parle le plus et, plus important encore, que les entreprises ont récemment intégré dans leurs processus CI. L'analyse statique agit comme l'une des étapes des soi-disant portes de qualité pour construire un produit logiciel fiable et de haute qualité. Nous pensons que l'analyse statique va devenir une pratique de développement de logiciels standard dans quelques années, tout comme les tests unitaires l'ont fait autrefois.

Pour conclure, je voudrais souligner une fois de plus que l'analyse dynamique et l'analyse statique ne sont que deux méthodes différentes, qui se complètent. Au final, toutes ces techniques ont pour seul objectif d'augmenter la qualité des logiciels et de réduire les dépenses de développement.

Références:

  1. Terminologie. Analyse de code statique .
  2. Terminologie. Analyse de code dynamique .
  3. Andrey Karpov. Analyse de code statique et dynamique .
  4. Andrey Karpov. Mythes sur l'analyse statique. Le troisième mythe - l'analyse dynamique est meilleure que l'analyse statique .
  5. Andrey Karpov. PVS-Studio ROI .

Source: https://habr.com/ru/post/fr461173/


All Articles